Subscribe to webhook events
const options = {
method: 'POST',
headers: {
'x-api-key': '<api-key>',
'x-api-secret': '<api-key>',
'x-connector-id': '<api-key>',
'x-owner-id': '<api-key>',
'x-session-token': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({events: []})
};
fetch('https://api.runmorph.dev/v1/webhooks', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));curl --request POST \
--url https://api.runmorph.dev/v1/webhooks \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--header 'x-api-secret: <api-key>' \
--header 'x-connector-id: <api-key>' \
--header 'x-owner-id: <api-key>' \
--header 'x-session-token: <api-key>' \
--data '{
"events": []
}'package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.runmorph.dev/v1/webhooks"
payload := strings.NewReader("{\n \"events\": []\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("x-api-secret", "<api-key>")
req.Header.Add("x-connector-id", "<api-key>")
req.Header.Add("x-owner-id", "<api-key>")
req.Header.Add("x-session-token", "<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))
}<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.runmorph.dev/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([
'events' => [
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>",
"x-api-secret: <api-key>",
"x-connector-id: <api-key>",
"x-owner-id: <api-key>",
"x-session-token: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}import requests
url = "https://api.runmorph.dev/v1/webhooks"
payload = { "events": [] }
headers = {
"x-api-key": "<api-key>",
"x-api-secret": "<api-key>",
"x-connector-id": "<api-key>",
"x-owner-id": "<api-key>",
"x-session-token": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)HttpResponse<String> response = Unirest.post("https://api.runmorph.dev/v1/webhooks")
.header("x-api-key", "<api-key>")
.header("x-api-secret", "<api-key>")
.header("x-connector-id", "<api-key>")
.header("x-owner-id", "<api-key>")
.header("x-session-token", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"events\": []\n}")
.asString();[
{
"object": "webhook",
"model": "<string>",
"trigger": "<string>",
"createdAt": "<string>",
"updatedAt": "<string>"
}
]{
"error": "MORPH::BAD_REQUEST",
"message": ""
}Webhooks
Subscribe to event
POST
/
v1
/
webhooks
Subscribe to webhook events
const options = {
method: 'POST',
headers: {
'x-api-key': '<api-key>',
'x-api-secret': '<api-key>',
'x-connector-id': '<api-key>',
'x-owner-id': '<api-key>',
'x-session-token': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({events: []})
};
fetch('https://api.runmorph.dev/v1/webhooks', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));curl --request POST \
--url https://api.runmorph.dev/v1/webhooks \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--header 'x-api-secret: <api-key>' \
--header 'x-connector-id: <api-key>' \
--header 'x-owner-id: <api-key>' \
--header 'x-session-token: <api-key>' \
--data '{
"events": []
}'package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.runmorph.dev/v1/webhooks"
payload := strings.NewReader("{\n \"events\": []\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("x-api-secret", "<api-key>")
req.Header.Add("x-connector-id", "<api-key>")
req.Header.Add("x-owner-id", "<api-key>")
req.Header.Add("x-session-token", "<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))
}<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.runmorph.dev/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([
'events' => [
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>",
"x-api-secret: <api-key>",
"x-connector-id: <api-key>",
"x-owner-id: <api-key>",
"x-session-token: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}import requests
url = "https://api.runmorph.dev/v1/webhooks"
payload = { "events": [] }
headers = {
"x-api-key": "<api-key>",
"x-api-secret": "<api-key>",
"x-connector-id": "<api-key>",
"x-owner-id": "<api-key>",
"x-session-token": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)HttpResponse<String> response = Unirest.post("https://api.runmorph.dev/v1/webhooks")
.header("x-api-key", "<api-key>")
.header("x-api-secret", "<api-key>")
.header("x-connector-id", "<api-key>")
.header("x-owner-id", "<api-key>")
.header("x-session-token", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"events\": []\n}")
.asString();[
{
"object": "webhook",
"model": "<string>",
"trigger": "<string>",
"createdAt": "<string>",
"updatedAt": "<string>"
}
]{
"error": "MORPH::BAD_REQUEST",
"message": ""
}Connectors Setup
Some connectors require a specific setup to support webhook subscription.
HubSpot
HubSpot
HubSpot requires two global webhooks to be configured at the HubSpot App level in your HubSpot developer portal.
Main Webhook Setup
- Navigate to Developer Hub > Your App
- Go to the “Webhooks” section
- Add the following webhook URL:
https://api.runmorph.dev/v1/hook/{orgId}/prod/hubspot/global/main
Card View Webhook Setup
If you plan to use theWidgetCardView model, you’ll need to configure an additional global webhook:- Navigate to the “CRM Card” section
- Click “Create a new card”
- In the “Data fetch URL” field, enter:
https://api.runmorph.dev/v1/hook/{orgId}/prod/hubspot/global/cardView
Replace
{orgId} with your actual organization ID in both webhook URLs.Authorizations
Body
application/jsonapplication/jwttext/plain
Minimum array length:
1Available options:
genericCompany::created, genericCompany::updated, genericCompany::deleted, genericContact::created, genericContact::updated, genericContact::deleted, genericUser::created, genericUser::updated, genericUser::deleted, genericWorkspace::created, genericWorkspace::updated, genericWorkspace::deleted, crmOpportunity::created, crmOpportunity::updated, crmOpportunity::deleted, crmStage::created, crmStage::updated, crmStage::deleted, crmPipeline::created, crmPipeline::updated, crmPipeline::deleted, crmEngagement::created, crmEngagement::updated, crmEngagement::deleted, telephonyCall::created, telephonyCall::updated, telephonyCall::deleted, telephonyCallTranscript::created, telephonyCallTranscript::updated, telephonyCallTranscript::deleted, schedulingEventType::created, schedulingEventType::updated, schedulingEventType::deleted, schedulingSlot::created, schedulingSlot::updated, schedulingSlot::deleted, schedulingEvent::created, schedulingEvent::updated, schedulingEvent::deleted, widgetCardView::created, widgetCardView::updated, widgetCardView::deleted, accountingInvoice::created, accountingInvoice::updated, accountingInvoice::deleted, accountingInvoiceLineItem::created, accountingInvoiceLineItem::updated, accountingInvoiceLineItem::deleted, accountingInvoiceItem::created, accountingInvoiceItem::updated, accountingInvoiceItem::deleted