API REFERENCE

Webhook API

REST API for reporting automation runs from Make.com, n8n, Zapier, or any HTTP client.
Base URL: https://hellhound.dev

POST /api/webhook/run-start
AUTHENTICATION

Authentication

All webhook endpoints require an API key sent in the X-API-Key header.

X-API-Key: hh_live_xxxxxxxxxxxxxxxxxxxxxxxxxx

Find your API key at hellhound.dev/account. Each account has one API key. If you need to rotate it, generate a new one from your account page.

Keep your API key private. Do not commit it to version control or expose it in client-side code. Use environment variables or a secrets manager to store it.

Unauthorized response:

If the key is missing or invalid, you will receive a 401 response:

{ "error": "Invalid or missing API key" }
BASE URL

Base URL

All API requests are made to:

https://hellhound.dev

Full example URL:

https://hellhound.dev/api/webhook/run-start
WEBHOOK ENDPOINT

POST /api/webhook/run-start

Report that an automation run has started. Call this at the beginning of your workflow. Returns a run_id to use when reporting the run end.

Full URL:

POST https://hellhound.dev/api/webhook/run-start

Headers:

Header Value
X-API-Key Your API key
Content-Type application/json

Request body:

Field Type Description
automation_name required string Name of the automation (e.g. "lead-pipeline")
source string Where the run was triggered from (e.g. "make", "n8n", "zapier", "custom")

Example request body:

{ "automation_name": "lead-pipeline", "source": "make" }

automation_name must match the name you use in run-end. If the automation does not exist yet, Hellhound creates it automatically on the first run-start. The source field is optional but helps you filter runs in the dashboard.

Response (200):

{ "run_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" }

Errors:

Status Meaning
400 Missing automation_name
401 Invalid or missing API key
402 Plan limit reached
429 Rate limit exceeded
500 Server error

curl example:

curl -X POST https://hellhound.dev/api/webhook/run-start \ -H "Content-Type: application/json" \ -H "X-API-Key: hh_live_xxxxxxxxxx" \ -d '{"automation_name": "lead-pipeline", "source": "make"}'
WEBHOOK ENDPOINT

POST /api/webhook/run-end

Report that an automation run has finished. Call this at the end of your workflow. Include the run_id from run-start to link the two events.

Full URL:

POST https://hellhound.dev/api/webhook/run-end

Headers:

Header Value
X-API-Key Your API key
Content-Type application/json

Request body:

Field Type Description
automation_name required string Name of the automation (must match run-start)
run_id string The run_id returned from run-start (recommended)
success required boolean Whether the run succeeded (true or false)
error_message string Error details when success is false

Example request body (success):

{ "automation_name": "lead-pipeline", "run_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "success": true }

Example request body (failure):

{ "automation_name": "lead-pipeline", "run_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "success": false, "error_message": "API returned 503 — CRM unavailable" }

success must be a boolean, not a string. Send true or false, not "true" or "false". Some platforms (like Make.com) send strings by default — make sure to convert.

Response (200):

{ "status": "recorded" }

Errors:

Status Meaning
400 Missing automation_name or success
401 Invalid or missing API key
402 Plan limit reached
429 Rate limit exceeded
500 Server error

curl example (success):

curl -X POST https://hellhound.dev/api/webhook/run-end \ -H "Content-Type: application/json" \ -H "X-API-Key: hh_live_xxxxxxxxxx" \ -d '{"automation_name": "lead-pipeline", "run_id": "a1b2c3d4...", "success": true}'

curl example (failure):

curl -X POST https://hellhound.dev/api/webhook/run-end \ -H "Content-Type: application/json" \ -H "X-API-Key: hh_live_xxxxxxxxxx" \ -d '{"automation_name": "lead-pipeline", "run_id": "a1b2c3d4...", "success": false, "error_message": "API returned 503"}'
REFERENCE

Request format

All requests must be sent as JSON with the Content-Type: application/json header.

Field types:

Type JSON format Example
string Wrapped in double quotes "lead-pipeline"
boolean Bare true or false (no quotes) true
number Bare number (no quotes) 42

Common mistake: Sending "true" (a string) instead of true (a boolean). Many no-code platforms default to strings. Make sure boolean fields are sent as actual JSON booleans.

REFERENCE

Error codes

All endpoints return standard HTTP status codes. Error responses include a JSON body with an error field.

Status Meaning What to do
200 Success Request was processed successfully
400 Bad request Check required fields are present and correctly typed
401 Unauthorized Check your API key is correct and sent in the X-API-Key header
402 Payment required Upgrade your plan or reduce the number of monitored automations
429 Rate limited Wait and retry. You are sending too many requests per second
500 Server error Retry after a few seconds. If persistent, contact support

Error response format:

{ "error": "Description of what went wrong" }
CODE EXAMPLES

Integration examples

Copy-paste examples for the most common platforms and languages.

Make.com

Make.com has a dedicated step-by-step setup guide. See Make.com Setup →

Node.js

Use the built-in fetch API (Node 18+) or any HTTP library.

// hellhound-report.js
const API_KEY = process.env.HELLHOUND_API_KEY
const BASE = 'https://hellhound.dev'
 
async function reportStart(automationName, source = 'custom') {
const res = await fetch(`${BASE}/api/webhook/run-start`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': API_KEY
},
body: JSON.stringify({
automation_name: automationName,
source
})
})
 
const data = await res.json()
return data.run_id
}
 
async function reportEnd(automationName, runId, success, errorMessage) {
await fetch(`${BASE}/api/webhook/run-end`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': API_KEY
},
body: JSON.stringify({
automation_name: automationName,
run_id: runId,
success,
error_message: errorMessage
})
})
}
 
// Usage
async function main() {
const runId = await reportStart('lead-pipeline', 'custom')
 
try {
await doWork()
await reportEnd('lead-pipeline', runId, true)
} catch (err) {
await reportEnd('lead-pipeline', runId, false, err.message)
}
}

Python

Using the requests library.

# hellhound_report.py
import os
import requests
 
API_KEY = os.environ['HELLHOUND_API_KEY']
BASE = 'https://hellhound.dev'
HEADERS = {
'Content-Type': 'application/json',
'X-API-Key': API_KEY
}
 
def report_start(automation_name, source='custom'):
res = requests.post(
f'{BASE}/api/webhook/run-start',
headers=HEADERS,
json={
'automation_name': automation_name,
'source': source
}
)
return res.json()['run_id']
 
def report_end(automation_name, run_id, success, error_message=None):
requests.post(
f'{BASE}/api/webhook/run-end',
headers=HEADERS,
json={
'automation_name': automation_name,
'run_id': run_id,
'success': success,
'error_message': error_message
}
)
 
# Usage
run_id = report_start('lead-pipeline')
 
try:
do_work()
report_end('lead-pipeline', run_id, True)
except Exception as e:
report_end('lead-pipeline', run_id, False, str(e))

Bash / curl

For shell scripts, consider using hellhound watch instead of the webhook API. It wraps your command with zero code changes: hellhound watch --name "my-job" --run "./script.sh"

Related documentation