Skip to main content
POST
/
api
/
v2
/
webhooks
Create a webhook
curl --request POST \
  --url https://agp.eu.hcompany.ai/api/v2/webhooks \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "url": "<string>",
  "enabled_events": [
    "<string>"
  ],
  "description": "<string>"
}
'
import requests

url = "https://agp.eu.hcompany.ai/api/v2/webhooks"

payload = {
"url": "<string>",
"enabled_events": ["<string>"],
"description": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({url: '<string>', enabled_events: ['<string>'], description: '<string>'})
};

fetch('https://agp.eu.hcompany.ai/api/v2/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://agp.eu.hcompany.ai/api/v2/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' => '<string>',
'enabled_events' => [
'<string>'
],
'description' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"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://agp.eu.hcompany.ai/api/v2/webhooks"

payload := strings.NewReader("{\n \"url\": \"<string>\",\n \"enabled_events\": [\n \"<string>\"\n ],\n \"description\": \"<string>\"\n}")

req, _ := http.NewRequest("POST", url, payload)

req.Header.Add("Authorization", "Bearer <token>")
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://agp.eu.hcompany.ai/api/v2/webhooks")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"url\": \"<string>\",\n \"enabled_events\": [\n \"<string>\"\n ],\n \"description\": \"<string>\"\n}")
.asString();
require 'uri'
require 'net/http'

url = URI("https://agp.eu.hcompany.ai/api/v2/webhooks")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"url\": \"<string>\",\n \"enabled_events\": [\n \"<string>\"\n ],\n \"description\": \"<string>\"\n}"

response = http.request(request)
puts response.read_body
Registers a webhook for your organization. The response includes the signing secret. This is the only time it is returned, so store it securely. Returns 201 with the created webhook object plus its secret.
The secret cannot be retrieved later. To replace it, use Rotate.

Request body

url
string
required
Target URL for deliveries. Must be https:// and publicly reachable: the platform sends a HEAD request at creation time and rejects the webhook if the endpoint cannot be reached. Any HTTP status counts as reachable; your endpoint does not need to accept HEAD.
enabled_events
string[]
default:["*"]
Event types delivered to this webhook. "*" subscribes to the session.status_updated firehose; granular session.* types are delivered only when listed explicitly. See the event catalog for supported types.
description
string
Optional label for the webhook (max 255 characters).

Examples

curl -X POST https://agp.eu.hcompany.ai/api/v2/webhooks \
  -H "Authorization: Bearer $HAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/hooks/h",
    "enabled_events": ["session.status_updated"],
    "description": "Production listener"
  }'
from hai_agents import Client

client = Client()

webhook = client.webhooks.create_webhook(
    url="https://example.com/hooks/h",
    enabled_events=["session.status_updated"],
    description="Production listener",
)
print(webhook.secret)  # shown only once; store it securely
import { HaiAgentsClient } from "hai-agents";

const client = new HaiAgentsClient();

const webhook = await client.webhooks.createWebhook({
  url: "https://example.com/hooks/h",
  enabledEvents: ["session.status_updated"],
  description: "Production listener",
});
console.log(webhook.secret); // shown only once; store it securely
Response
{
  "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "url": "https://example.com/hooks/h",
  "enabled_events": ["session.status_updated"],
  "description": "Production listener",
  "disabled": false,
  "last_delivery_status": null,
  "last_delivery_error": null,
  "last_delivery_at": null,
  "last_success_at": null,
  "consecutive_failures": 0,
  "created_at": "2026-06-11T15:04:05Z",
  "updated_at": "2026-06-11T15:04:05Z",
  "secret": "whsec_k3TQyhq2mPv8WdJ4cN7xLbR9sF1aZ6uE0gYoHiC5jXw"
}

Errors

StatusCause
400Organization webhook limit reached (10), URL does not resolve to a public address, or the endpoint could not be reached.
422Body failed validation: non-https URL, empty or unknown enabled_events.