curl --request POST \
--url https://app.hookie.ai/{workspace}/{project}/{webhook}/{dataset} \
--header 'Content-Type: application/json' \
--data '"<unknown>"'const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify('<unknown>')
};
fetch('https://app.hookie.ai/{workspace}/{project}/{webhook}/{dataset}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://app.hookie.ai/{workspace}/{project}/{webhook}/{dataset}"
payload = "<unknown>"
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"submission_id": "<string>",
"idempotent": true
}{
"submission_id": "<string>",
"routed": [
"<string>"
],
"records": 123
}{
"error": "<string>",
"retry_after": 123,
"upgrade_url": "<string>"
}{
"error": "<string>"
}{
"error": "<string>",
"retry_after": 123,
"upgrade_url": "<string>"
}{
"error": "<string>",
"retry_after": 123,
"upgrade_url": "<string>"
}{
"error": "<string>",
"retry_after": 123,
"upgrade_url": "<string>"
}{
"error": "<string>",
"retry_after": 123,
"upgrade_url": "<string>"
}Ingest an event through the public webhook URL, naming its dataset
Four-segment form of the public webhook URL. POST only (index.ts:190); other methods fall through to the SPA. The fourth segment must be the endpoint’s OWN dataset: any other value is refused with 403. It used to override the dataset with any dataset in the project, which let anyone holding a public endpoint URL (one embedded in an HTML form, say) write into every dataset in the project and set off its destinations, triggers and workflows. To route one source into several datasets, use an ingest key: POST /v1/ingest//.
curl --request POST \
--url https://app.hookie.ai/{workspace}/{project}/{webhook}/{dataset} \
--header 'Content-Type: application/json' \
--data '"<unknown>"'const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify('<unknown>')
};
fetch('https://app.hookie.ai/{workspace}/{project}/{webhook}/{dataset}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://app.hookie.ai/{workspace}/{project}/{webhook}/{dataset}"
payload = "<unknown>"
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"submission_id": "<string>",
"idempotent": true
}{
"submission_id": "<string>",
"routed": [
"<string>"
],
"records": 123
}{
"error": "<string>",
"retry_after": 123,
"upgrade_url": "<string>"
}{
"error": "<string>"
}{
"error": "<string>",
"retry_after": 123,
"upgrade_url": "<string>"
}{
"error": "<string>",
"retry_after": 123,
"upgrade_url": "<string>"
}{
"error": "<string>",
"retry_after": 123,
"upgrade_url": "<string>"
}{
"error": "<string>",
"retry_after": 123,
"upgrade_url": "<string>"
}Headers
Optional. A repeat key short-circuits with 200 before quota is charged.
Path Parameters
Workspace (tenant) slug; must not be a reserved root (api, admin, stripe, v1, assets, settings, favicon.ico, robots.txt, sitemap.xml, index.html, app.js, styles.css, export.js, portal, brand, trial-info, .well-known, mcp).
Project slug within the workspace.
Webhook slug — the credential. Only an enabled webhook matches.
Dataset to store the record in, overriding the webhook's configured dataset for this request. No validation is performed; the name is used as given.
Body
Same parsing as the 3-segment form: urlencoded and multipart are flattened (repeats become arrays, file parts become {filename, type, size} with the bytes discarded); every other Content-Type is parsed as JSON; an empty body becomes {}; a non-object payload is wrapped as {"value": }. Over 1,000,000 bytes yields 413.
Any JSON value.
Response
Idempotent replay — a submission with this Idempotency-Key already exists for the tenant. No quota is charged when the duplicate is detected up front; a request that loses the unique-index race has already been counted against the monthly quota.