curl --request GET \
--url https://api.waterr.ai/v1/skills/{id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.waterr.ai/v1/skills/{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.waterr.ai/v1/skills/{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.waterr.ai/v1/skills/{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.waterr.ai/v1/skills/{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.waterr.ai/v1/skills/{id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.waterr.ai/v1/skills/{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_body{
"id": "9f0e1d2c-3b4a-5968-8776-655443322110",
"name": "book_demo",
"trigger": "book_demo: when the participant asks to see the product live.",
"instructions": "Confirm intent first. Then collect their preferred time and timezone, one question per turn, and call schedule_demo once.",
"active": true,
"membership_id": "a1b2c3d4-e5f6-7890-abcd-ef0123456789",
"gated_tool_names": [
"schedule_demo"
],
"scenarios": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"active": true,
"position": 123
}
],
"created_at": "2026-09-10T09:00:00.000Z",
"updated_at": "2026-09-10T09:00:00.000Z"
}Get a skill
Fetch one skill, including the scenarios it is attached to.
curl --request GET \
--url https://api.waterr.ai/v1/skills/{id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.waterr.ai/v1/skills/{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.waterr.ai/v1/skills/{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.waterr.ai/v1/skills/{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.waterr.ai/v1/skills/{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.waterr.ai/v1/skills/{id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.waterr.ai/v1/skills/{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_body{
"id": "9f0e1d2c-3b4a-5968-8776-655443322110",
"name": "book_demo",
"trigger": "book_demo: when the participant asks to see the product live.",
"instructions": "Confirm intent first. Then collect their preferred time and timezone, one question per turn, and call schedule_demo once.",
"active": true,
"membership_id": "a1b2c3d4-e5f6-7890-abcd-ef0123456789",
"gated_tool_names": [
"schedule_demo"
],
"scenarios": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"active": true,
"position": 123
}
],
"created_at": "2026-09-10T09:00:00.000Z",
"updated_at": "2026-09-10T09:00:00.000Z"
}Authorizations
API key from waterr.ai/settings?tab=api-keys. Send as Authorization: Bearer wai_<your_key>.
Path Parameters
Skill UUID.
Response
The skill.
An invokable instruction pack. Only the one-line trigger sits in the agent's prompt each turn; the full instructions load when the agent invokes the skill mid-meeting and are dropped when the flow completes.
"9f0e1d2c-3b4a-5968-8776-655443322110"
Identifier the agent passes to invoke_skill. Unique per account.
64^[a-zA-Z0-9_-]{1,64}$"book_demo"
One line describing WHEN to invoke this skill. Lives in the base prompt on every turn — keep it short and specific.
500"book_demo: when the participant asks to see the product live."
The instruction pack, delivered to the agent only after it invokes the skill.
8000"Confirm intent first. Then collect their preferred time and timezone, one question per turn, and call schedule_demo once."
Account-level kill-switch for the definition.
true
"a1b2c3d4-e5f6-7890-abcd-ef0123456789"
Custom-function names that refuse to execute until this skill is invoked. [] means the skill is purely behavioural.
20^[a-zA-Z0-9_-]{1,64}$["schedule_demo"]
Scenarios this skill is attached to. Returned only on the single-skill read.
Show child attributes
Show child attributes
"2026-09-10T09:00:00.000Z"
"2026-09-10T09:00:00.000Z"

