Create endpoint
curl --request POST \
--url https://api.reclack.com/v1/webhooks \
--header 'Api-Key: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"url": "https://acme.dev/hooks/reclack",
"event_types": [
"invoice.paid",
"subscription.renewed"
],
"description": "Billing events for the production app"
}
'import requests
url = "https://api.reclack.com/v1/webhooks"
payload = {
"url": "https://acme.dev/hooks/reclack",
"event_types": ["invoice.paid", "subscription.renewed"],
"description": "Billing events for the production app"
}
headers = {
"Api-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Api-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
url: 'https://acme.dev/hooks/reclack',
event_types: ['invoice.paid', 'subscription.renewed'],
description: 'Billing events for the production app'
})
};
fetch('https://api.reclack.com/v1/webhooks', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.reclack.com/v1/webhooks",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'url' => 'https://acme.dev/hooks/reclack',
'event_types' => [
'invoice.paid',
'subscription.renewed'
],
'description' => 'Billing events for the production app'
]),
CURLOPT_HTTPHEADER => [
"Api-Key: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.reclack.com/v1/webhooks"
payload := strings.NewReader("{\n \"url\": \"https://acme.dev/hooks/reclack\",\n \"event_types\": [\n \"invoice.paid\",\n \"subscription.renewed\"\n ],\n \"description\": \"Billing events for the production app\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Api-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.reclack.com/v1/webhooks")
.header("Api-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"url\": \"https://acme.dev/hooks/reclack\",\n \"event_types\": [\n \"invoice.paid\",\n \"subscription.renewed\"\n ],\n \"description\": \"Billing events for the production app\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.reclack.com/v1/webhooks")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Api-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"url\": \"https://acme.dev/hooks/reclack\",\n \"event_types\": [\n \"invoice.paid\",\n \"subscription.renewed\"\n ],\n \"description\": \"Billing events for the production app\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": "whe_7Fh2PqX9",
"url": "https://acme.dev/hooks/reclack",
"status": "active",
"description": "Billing events for the production app",
"event_types": [
"invoice.paid",
"subscription.renewed"
],
"secret": "whsec_9f1c4a2b8e7d0356",
"created_at": "2026-10-18T22:07:41Z",
"updated_at": "2026-10-18T22:07:41Z"
}
}{
"error": {
"type": "invalid_request_error",
"code": "price_not_found",
"message": "No price was found for that id"
}
}{
"error": {
"type": "invalid_request_error",
"code": "price_not_found",
"message": "No price was found for that id"
}
}{
"error": {
"type": "invalid_request_error",
"code": "price_not_found",
"message": "No price was found for that id"
}
}Webhooks
Create Webhook Endpoint
Register an endpoint to receive events.
POST
/
v1
/
webhooks
Create endpoint
curl --request POST \
--url https://api.reclack.com/v1/webhooks \
--header 'Api-Key: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"url": "https://acme.dev/hooks/reclack",
"event_types": [
"invoice.paid",
"subscription.renewed"
],
"description": "Billing events for the production app"
}
'import requests
url = "https://api.reclack.com/v1/webhooks"
payload = {
"url": "https://acme.dev/hooks/reclack",
"event_types": ["invoice.paid", "subscription.renewed"],
"description": "Billing events for the production app"
}
headers = {
"Api-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Api-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
url: 'https://acme.dev/hooks/reclack',
event_types: ['invoice.paid', 'subscription.renewed'],
description: 'Billing events for the production app'
})
};
fetch('https://api.reclack.com/v1/webhooks', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.reclack.com/v1/webhooks",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'url' => 'https://acme.dev/hooks/reclack',
'event_types' => [
'invoice.paid',
'subscription.renewed'
],
'description' => 'Billing events for the production app'
]),
CURLOPT_HTTPHEADER => [
"Api-Key: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.reclack.com/v1/webhooks"
payload := strings.NewReader("{\n \"url\": \"https://acme.dev/hooks/reclack\",\n \"event_types\": [\n \"invoice.paid\",\n \"subscription.renewed\"\n ],\n \"description\": \"Billing events for the production app\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Api-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.reclack.com/v1/webhooks")
.header("Api-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"url\": \"https://acme.dev/hooks/reclack\",\n \"event_types\": [\n \"invoice.paid\",\n \"subscription.renewed\"\n ],\n \"description\": \"Billing events for the production app\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.reclack.com/v1/webhooks")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Api-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"url\": \"https://acme.dev/hooks/reclack\",\n \"event_types\": [\n \"invoice.paid\",\n \"subscription.renewed\"\n ],\n \"description\": \"Billing events for the production app\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": "whe_7Fh2PqX9",
"url": "https://acme.dev/hooks/reclack",
"status": "active",
"description": "Billing events for the production app",
"event_types": [
"invoice.paid",
"subscription.renewed"
],
"secret": "whsec_9f1c4a2b8e7d0356",
"created_at": "2026-10-18T22:07:41Z",
"updated_at": "2026-10-18T22:07:41Z"
}
}{
"error": {
"type": "invalid_request_error",
"code": "price_not_found",
"message": "No price was found for that id"
}
}{
"error": {
"type": "invalid_request_error",
"code": "price_not_found",
"message": "No price was found for that id"
}
}{
"error": {
"type": "invalid_request_error",
"code": "price_not_found",
"message": "No price was found for that id"
}
}Overview
Register an endpoint. The response carries the signing secret, shown once. Store it before you close the terminal, and verify every delivery against it.Authorizations
Your Reclack API key. The prefix decides the environment: rk_sandbox_ for test chains, rk_live_ for production.
Body
application/json
Response
Created
Show child attributes
Show child attributes

