Get Webhook
curl --request GET \
--url https://api.shoal.xyz/v1/webhooks/{id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.shoal.xyz/v1/webhooks/{id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.shoal.xyz/v1/webhooks/{id}', 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.shoal.xyz/v1/webhooks/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.shoal.xyz/v1/webhooks/{id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.shoal.xyz/v1/webhooks/{id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.shoal.xyz/v1/webhooks/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_bodyWebhooks
Get Webhook
Get a single webhook with recent delivery history
GET
/
v1
/
webhooks
/
{id}
Get Webhook
curl --request GET \
--url https://api.shoal.xyz/v1/webhooks/{id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.shoal.xyz/v1/webhooks/{id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.shoal.xyz/v1/webhooks/{id}', 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.shoal.xyz/v1/webhooks/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.shoal.xyz/v1/webhooks/{id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.shoal.xyz/v1/webhooks/{id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.shoal.xyz/v1/webhooks/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_bodyReturns a webhook’s configuration and its 20 most recent delivery attempts. Use this to debug delivery issues or confirm events are arriving.
Webhook management is available only on plans that include webhook access.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | integer | Yes | Webhook ID |
Request
cURL
curl -X GET "https://api.shoal.xyz/v1/webhooks/12" \
-H "Authorization: Bearer YOUR_API_KEY"
Python
import os, requests
API_KEY = os.environ.get("SHOAL_API_KEY", "YOUR_API_KEY")
r = requests.get(
"https://api.shoal.xyz/v1/webhooks/12",
headers={"Authorization": f"Bearer {API_KEY}"},
)
print(r.json())
JavaScript
const API_KEY = process.env.SHOAL_API_KEY || 'YOUR_API_KEY';
const res = await fetch('https://api.shoal.xyz/v1/webhooks/12', {
headers: { Authorization: `Bearer ${API_KEY}` },
});
console.log(await res.json());
Response (200)
{
"data": {
"id": 12,
"url": "https://example.com/shoal-webhook",
"secret_hint": "****f6a8",
"event_types": ["radar", "signal"],
"active": true,
"created_at": "2026-03-10T12:00:00Z",
"updated_at": "2026-03-10T12:00:00Z"
},
"recent_deliveries": [
{
"id": 456,
"event_type": "radar",
"event_id": 1234,
"status": "success",
"attempts": 1,
"response_status": 200,
"created_at": "2026-03-10T14:30:00Z",
"last_attempt_at": "2026-03-10T14:30:01Z"
},
{
"id": 455,
"event_type": "signal",
"event_id": 5678,
"status": "failed",
"attempts": 5,
"response_status": 500,
"created_at": "2026-03-10T13:00:00Z",
"last_attempt_at": "2026-03-10T15:00:00Z"
}
]
}
Delivery Statuses
| Status | Description |
|---|---|
pending | Queued or awaiting retry |
success | Delivered successfully (2xx response) |
failed | All retry attempts exhausted |
Errors
| Status | Error | Cause |
|---|---|---|
| 400 | Webhook id is required | Missing or invalid ID |
| 404 | Webhook not found | ID doesn’t exist or belongs to another account |
⌘I