curl --request POST \
--url https://api.contractorscloud.com/api/v1/webhooks \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"endpoint": "https://example.com/webhooks/contractors-cloud",
"company_id": 6
}
'import requests
url = "https://api.contractorscloud.com/api/v1/webhooks"
payload = {
"endpoint": "https://example.com/webhooks/contractors-cloud",
"company_id": 6
}
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({endpoint: 'https://example.com/webhooks/contractors-cloud', company_id: 6})
};
fetch('https://api.contractorscloud.com/api/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.contractorscloud.com/api/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([
'endpoint' => 'https://example.com/webhooks/contractors-cloud',
'company_id' => 6
]),
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://api.contractorscloud.com/api/v1/webhooks"
payload := strings.NewReader("{\n \"endpoint\": \"https://example.com/webhooks/contractors-cloud\",\n \"company_id\": 6\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://api.contractorscloud.com/api/v1/webhooks")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"endpoint\": \"https://example.com/webhooks/contractors-cloud\",\n \"company_id\": 6\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.contractorscloud.com/api/v1/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 \"endpoint\": \"https://example.com/webhooks/contractors-cloud\",\n \"company_id\": 6\n}"
response = http.request(request)
puts response.read_body{
"id": "a3d8f2e6-1c4b-4a9d-8e3f-2b5a7c9d4f60",
"tenant_id": 12,
"company_id": 6,
"user_id": 1159,
"endpoint": "https://example.com/webhooks/contractors-cloud",
"error_rate": 0,
"is_enabled": true,
"signing_secret": "5f2a9c3e8d1b6f4a7c2e9d5b3f8a1c6e4d7b2f9a",
"created_at": "2025-02-11 09:00:00",
"updated_at": "2025-02-11 09:00:00"
}{
"message": "Unauthenticated."
}{
"message": "The first name field is required.",
"errors": {
"first_name": [
"The first name field is required."
]
}
}Create webhook
Creates a webhook and returns the created resource, including its signing_secret. Save the secret when you create the webhook — it’s returned on every response for this webhook, but there’s no separate way to retrieve or rotate it; to change it, delete this webhook and create a new one.
curl --request POST \
--url https://api.contractorscloud.com/api/v1/webhooks \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"endpoint": "https://example.com/webhooks/contractors-cloud",
"company_id": 6
}
'import requests
url = "https://api.contractorscloud.com/api/v1/webhooks"
payload = {
"endpoint": "https://example.com/webhooks/contractors-cloud",
"company_id": 6
}
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({endpoint: 'https://example.com/webhooks/contractors-cloud', company_id: 6})
};
fetch('https://api.contractorscloud.com/api/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.contractorscloud.com/api/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([
'endpoint' => 'https://example.com/webhooks/contractors-cloud',
'company_id' => 6
]),
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://api.contractorscloud.com/api/v1/webhooks"
payload := strings.NewReader("{\n \"endpoint\": \"https://example.com/webhooks/contractors-cloud\",\n \"company_id\": 6\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://api.contractorscloud.com/api/v1/webhooks")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"endpoint\": \"https://example.com/webhooks/contractors-cloud\",\n \"company_id\": 6\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.contractorscloud.com/api/v1/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 \"endpoint\": \"https://example.com/webhooks/contractors-cloud\",\n \"company_id\": 6\n}"
response = http.request(request)
puts response.read_body{
"id": "a3d8f2e6-1c4b-4a9d-8e3f-2b5a7c9d4f60",
"tenant_id": 12,
"company_id": 6,
"user_id": 1159,
"endpoint": "https://example.com/webhooks/contractors-cloud",
"error_rate": 0,
"is_enabled": true,
"signing_secret": "5f2a9c3e8d1b6f4a7c2e9d5b3f8a1c6e4d7b2f9a",
"created_at": "2025-02-11 09:00:00",
"updated_at": "2025-02-11 09:00:00"
}{
"message": "Unauthenticated."
}{
"message": "The first name field is required.",
"errors": {
"first_name": [
"The first name field is required."
]
}
}Authorizations
Authenticate with an API access token in the Authorization header: Authorization: Bearer <token>. Create a token from the API Access Tokens page in Contractors Cloud, under Integrations.
Body
The URL deliveries are POSTed to. Required when creating a webhook; cannot be set to an empty value when updating.
"https://example.com/webhooks/contractors-cloud"
The id of a company in your organization to scope this webhook to. Optional; omit or send null to fire for matching events across your whole organization.
6
Whether the webhook receives event deliveries. Optional; defaults to true if omitted.
true
Response
The created webhook.
The webhook's unique identifier.
"a3d8f2e6-1c4b-4a9d-8e3f-2b5a7c9d4f60"
The id of your organization's account. Null if not recorded.
12
The id of the company this webhook is scoped to. Null means the webhook fires for matching events across every company in your organization; set it to scope deliveries to one company.
6
The id of the user who created this webhook. Null if not recorded.
1159
The URL that event deliveries are sent to as an HTTP POST request. An https:// URL is strongly recommended, since deliveries include your signing_secret-derived signature and potentially sensitive resource data, though the API doesn't enforce a particular scheme.
"https://example.com/webhooks/contractors-cloud"
The percentage of this webhook's delivery attempts that failed over roughly the last 90 days. This is an informational health signal only — it doesn't affect delivery, and a high value doesn't disable the webhook.
0 <= x <= 1000
Whether this webhook receives deliveries for its subscribed events. Disabled webhooks receive no event deliveries, but can still receive test sends.
true
The per-webhook secret key used to sign every delivery. Returned on every response for this webhook, including list results — treat it as a credential. There's no separate endpoint to retrieve or rotate it; to change it, delete this webhook and create a new one. See Verifying signatures for how to use it.
"5f2a9c3e8d1b6f4a7c2e9d5b3f8a1c6e4d7b2f9a"
Timestamp when the webhook was created, formatted as YYYY-MM-DD HH:MM:SS. Null if not recorded.
"2025-01-05 08:15:00"
Timestamp when the webhook was last updated, formatted as YYYY-MM-DD HH:MM:SS. Null if not recorded.
"2025-01-05 08:15:00"