Configure Slack Webhook
curl --request POST \
--url https://api.tornadoapi.io/user/slack \
--header 'Content-Type: application/json' \
--header 'x-api-key: <x-api-key>' \
--data '
{
"webhook_url": "<string>",
"notify_level": "<string>"
}
'import requests
url = "https://api.tornadoapi.io/user/slack"
payload = {
"webhook_url": "<string>",
"notify_level": "<string>"
}
headers = {
"x-api-key": "<x-api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<x-api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({webhook_url: '<string>', notify_level: '<string>'})
};
fetch('https://api.tornadoapi.io/user/slack', 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.tornadoapi.io/user/slack",
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([
'webhook_url' => '<string>',
'notify_level' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <x-api-key>"
],
]);
$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.tornadoapi.io/user/slack"
payload := strings.NewReader("{\n \"webhook_url\": \"<string>\",\n \"notify_level\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<x-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.tornadoapi.io/user/slack")
.header("x-api-key", "<x-api-key>")
.header("Content-Type", "application/json")
.body("{\n \"webhook_url\": \"<string>\",\n \"notify_level\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tornadoapi.io/user/slack")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<x-api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"webhook_url\": \"<string>\",\n \"notify_level\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"message": "Slack webhook configured successfully",
"configured": true,
"notify_level": "all"
}
User
Configure Slack Webhook
Configure Slack notifications for job failures
POST
/
user
/
slack
Configure Slack Webhook
curl --request POST \
--url https://api.tornadoapi.io/user/slack \
--header 'Content-Type: application/json' \
--header 'x-api-key: <x-api-key>' \
--data '
{
"webhook_url": "<string>",
"notify_level": "<string>"
}
'import requests
url = "https://api.tornadoapi.io/user/slack"
payload = {
"webhook_url": "<string>",
"notify_level": "<string>"
}
headers = {
"x-api-key": "<x-api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<x-api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({webhook_url: '<string>', notify_level: '<string>'})
};
fetch('https://api.tornadoapi.io/user/slack', 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.tornadoapi.io/user/slack",
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([
'webhook_url' => '<string>',
'notify_level' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <x-api-key>"
],
]);
$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.tornadoapi.io/user/slack"
payload := strings.NewReader("{\n \"webhook_url\": \"<string>\",\n \"notify_level\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<x-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.tornadoapi.io/user/slack")
.header("x-api-key", "<x-api-key>")
.header("Content-Type", "application/json")
.body("{\n \"webhook_url\": \"<string>\",\n \"notify_level\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.tornadoapi.io/user/slack")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<x-api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"webhook_url\": \"<string>\",\n \"notify_level\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"message": "Slack webhook configured successfully",
"configured": true,
"notify_level": "all"
}
Overview
Configure a Slack incoming webhook to receive notifications when jobs fail. You can choose to receive all failure notifications, errors only (technical failures), or warnings only (content issues like private/unavailable videos). The webhook URL is stored securely and encrypted at rest.Header Parameters
string
required
Your API key for authentication
Request
string
required
Slack incoming webhook URL. Must start with
https://hooks.slack.com/services/.string
default:"all"
Controls which failure types trigger a Slack notification:
all— Both errors and warnings (default)errors_only— Only technical failures (rate limits, bot detection, connection errors)warnings_only— Only content issues (private video, members-only, geo-blocked, unavailable)
Examples
curl -X POST "https://api.tornadoapi.io/user/slack" \
-H "x-api-key: sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"webhook_url": "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX"
}'
curl -X POST "https://api.tornadoapi.io/user/slack" \
-H "x-api-key: sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"webhook_url": "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX",
"notify_level": "errors_only"
}'
curl -X POST "https://api.tornadoapi.io/user/slack" \
-H "x-api-key: sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"webhook_url": "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX",
"notify_level": "warnings_only"
}'
Success Response
{
"message": "Slack webhook configured successfully",
"configured": true,
"notify_level": "all"
}
Error Responses
{
"error": "Slack webhook URL must start with https://hooks.slack.com/services/"
}
{
"error": "Invalid notify_level. Must be 'all', 'errors_only', or 'warnings_only'"
}
{
"error": "Invalid API Key"
}
{
"error": "Slack webhook configuration is temporarily unavailable"
}
If you already have a Slack webhook configured, calling this endpoint again will replace the existing webhook and notify level.
Notification Format
When a job fails, Tornado sends a Slack message with a colored attachment:- Red (
:x:) for technical errors (rate limits, connection issues, bot detection) - Orange (
:warning:) for content warnings (private video, members-only, geo-blocked, unavailable)
Notify Level Reference
| Level | Errors (red) | Warnings (orange) |
|---|---|---|
all | ✓ | ✓ |
errors_only | ✓ | ✗ |
warnings_only | ✗ | ✓ |
What counts as an error vs warning?
| Type | Examples |
|---|---|
| Error (technical) | Bot detection, rate limited, connection error, upload failed, processing failed |
| Warning (content) | Private video, members-only, video unavailable, age-restricted, geo-blocked, channel terminated, copyright restricted |
This API route configures failure notifications. Completion summaries can also be enabled through the dashboard configuration; they are separate from
notify_level and may aggregate several completed jobs.Was this page helpful?