Returns the URL to POST to and the secret to send with it. surfaceKind: "channel" needs a channelId already mapped to this Worker — an unmapped room, and a DM id, are both refused; "dm" needs the slackUserId of the person. On a room mapped to a client, workClientId names that client. For a sender that cannot set a header, secretKind: "link" with linkAcknowledged: true answers a link with the secret in it.
The secret in the response, and the link in link mode, are shown once and the secret is stored hashed. Nothing can read them back — if you lose them, your only option is to rotate, which breaks whatever is already using the old one. Treat a link like a password.
An organization-scoped API key, minted in control under Settings → API keys. Every failure to authenticate answers one identical 401: "Provide a valid organization-scoped API key or an active session." Each operation names the one scope it is filed under, <resource>:<read|write>, where the resource is the first path segment after /api/v1/; a key minted today carries all 22 of them. Scopes are RECORDED — on the key and on every audit row — and are not yet enforced: no request is refused for want of one.
header (absent) mints a whsec_… secret the sender puts in Authorization: Bearer. link mints a whlnk_… secret carried in the URL, for a sender that takes only a web address (Calendly, Cal.com), and answers link beside secret. A rotate without link turns a link webhook into a header one.
Required, and true, with secretKind: "link": you accept that the tool you paste the link into keeps a copy of it, and that a link carrying a secret is less safe than a secret sent in a header. Without it the call is a 400 and nothing is changed.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Ergoly","description":"How to manage your agency on Ergoly","colors":{"primary":"#079b9b","light":"#3cd3cf","dark":"#0f7170"},"logo":{"light":"https://mintcdn.com/ergoly/-drdYd6uXChmiNIn/logo/light.png?fit=max\u0026auto=format\u0026n=-drdYd6uXChmiNIn\u0026q=85\u0026s=a9084e9caaf8656a821bf02426e31c05","dark":"https://mintcdn.com/ergoly/-drdYd6uXChmiNIn/logo/dark.png?fit=max\u0026auto=format\u0026n=-drdYd6uXChmiNIn\u0026q=85\u0026s=2c7c39ae6542910294a1183134fda8ff","href":"https://www.ergoly.ai"},"favicon":"https://mintcdn.com/ergoly/-drdYd6uXChmiNIn/favicon.png?fit=max\u0026auto=format\u0026n=-drdYd6uXChmiNIn\u0026q=85\u0026s=9e5baceff3d9e2c0f0d473b3a7c5d40b","api":{"playground":{"display":"interactive","proxy":true},"examples":{"defaults":"required","languages":["curl","javascript","python"]}},"background":{"color":{"light":"#f2f3f3","dark":"#282828"}},"navbar":{"links":[{"href":"https://www.ergoly.ai/support","label":"Support"}],"primary":{"type":"button","label":"Sign in","href":"https://control.ergoly.ai/"}},"footer":{"socials":{"website":"https://www.ergoly.ai","linkedin":"https://www.linkedin.com/company/ergoly","github":"https://github.com/ergoly-ai"}},"seo":{"metatags":{"canonical":"https://docs.ergoly.ai"}},"fonts":{"family":"Satoshi","source":"fonts/Satoshi-Variable.woff2","format":"woff2"},"banner":{"content":"Ergoly is hiring. \u003ca href=\"https://www.ergoly.ai/jobs\">Apply today\u003c/a>.","dismissible":true},"contextual":{"options":["copy","view","chatgpt","claude","perplexity","mcp","cursor","vscode"],"display":"header"},"interaction":{"drilldown":false},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"ergoly","hasAudioNarration":false,"actualSubdomain":"ergoly","customDomains":["docs.ergoly.ai"],"gitSource":{"type":"github","owner":"ergoly-ai","repo":"docs","deployBranch":"main","contentDirectory":"","isPrivate":false,"mountPath":"","label":"","_id":"6af1063edce746e0972c5b68"},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6af1344bc7dcf404baff164b","clientVersion":"0.0.4088","searchFilterCounts":[{"language":"default","tag":"API","count":72},{"language":"default","tag":"Docs","count":49},{"language":"default","tag":"Workers","count":33},{"language":"default","tag":"Connections","count":26},{"language":"default","tag":"Channels","count":14},{"language":"default","tag":"Changelog","count":12},{"language":"default","tag":"Releases","count":12},{"language":"default","tag":"Tasks","count":11},{"language":"default","tag":"Clients","count":9},{"language":"default","tag":"Company","count":9}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":true,"hasWebMcpPermissions":true,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"comment-mode","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"api-reference/webhooks/create-a-webhook","slug":"/api-reference/webhooks/create-a-webhook","pageMetadata":{"title":"Create a webhook","description":"Returns the URL to POST to and the secret to send with it. `surfaceKind: \"channel\"` needs a `channelId` already mapped to this Worker — an unmapped room, and a DM id, are both refused; `\"dm\"` needs the `slackUserId` of the person. On a room mapped to a client, `workClientId` names that client. For a sender that cannot set a header, `secretKind: \"link\"` with `linkAcknowledged: true` answers a `link` with the secret in it.\n\n**The `secret` in the response, and the `link` in link mode, are shown once and the secret is stored hashed. Nothing can read them back — if you lose them, your only option is to rotate, which breaks whatever is already using the old one. Treat a link like a password.**","deprecated":null,"version":null,"openapi":"/openapi.json post /api/v1/webhooks","href":"/api-reference/webhooks/create-a-webhook","autogeneratedByOpenApi":true},"description":{"compiledSource":"\"use strict\";\nconst {Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n code: \"code\",\n p: \"p\",\n strong: \"strong\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsxs(_Fragment, {\n children: [_jsxs(_components.p, {\n children: [\"Returns the URL to POST to and the secret to send with it. \", _jsx(_components.code, {\n children: \"surfaceKind: \\\"channel\\\"\"\n }), \" needs a \", _jsx(_components.code, {\n children: \"channelId\"\n }), \" already mapped to this Worker — an unmapped room, and a DM id, are both refused; \", _jsx(_components.code, {\n children: \"\\\"dm\\\"\"\n }), \" needs the \", _jsx(_components.code, {\n children: \"slackUserId\"\n }), \" of the person. On a room mapped to a client, \", _jsx(_components.code, {\n children: \"workClientId\"\n }), \" names that client. For a sender that cannot set a header, \", _jsx(_components.code, {\n children: \"secretKind: \\\"link\\\"\"\n }), \" with \", _jsx(_components.code, {\n children: \"linkAcknowledged: true\"\n }), \" answers a \", _jsx(_components.code, {\n children: \"link\"\n }), \" with the secret in it.\"]\n }), \"\\n\", _jsx(_components.p, {\n children: _jsxs(_components.strong, {\n children: [\"The \", _jsx(_components.code, {\n children: \"secret\"\n }), \" in the response, and the \", _jsx(_components.code, {\n children: \"link\"\n }), \" in link mode, are shown once and the secret is stored hashed. Nothing can read them back — if you lose them, your only option is to rotate, which breaks whatever is already using the old one. Treat a link like a password.\"]\n })\n })]\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){return _jsx(_Fragment,{})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Create a webhook","description":"Returns the URL to POST to and the secret to send with it. `surfaceKind: \"channel\"` needs a `channelId` already mapped to this Worker — an unmapped room, and a DM id, are both refused; `\"dm\"` needs the `slackUserId` of the person. On a room mapped to a client, `workClientId` names that client. For a sender that cannot set a header, `secretKind: \"link\"` with `linkAcknowledged: true` answers a `link` with the secret in it.\n\n**The `secret` in the response, and the `link` in link mode, are shown once and the secret is stored hashed. Nothing can read them back — if you lose them, your only option is to rotate, which breaks whatever is already using the old one. Treat a link like a password.**","deprecated":null,"version":null,"openapi":"/openapi.json post /api/v1/webhooks","href":"/api-reference/webhooks/create-a-webhook","autogeneratedByOpenApi":true}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":[],"openApiReferenceData":{"operation":{"operationId":"createWebhook","summary":"Create a webhook","description":"Returns the URL to POST to and the secret to send with it. `surfaceKind: \"channel\"` needs a `channelId` already mapped to this Worker — an unmapped room, and a DM id, are both refused; `\"dm\"` needs the `slackUserId` of the person. On a room mapped to a client, `workClientId` names that client. For a sender that cannot set a header, `secretKind: \"link\"` with `linkAcknowledged: true` answers a `link` with the secret in it.\n\n**The `secret` in the response, and the `link` in link mode, are shown once and the secret is stored hashed. Nothing can read them back — if you lose them, your only option is to rotate, which breaks whatever is already using the old one. Treat a link like a password.**","tags":["webhooks"],"security":["59622cc5-91f9-4e7c-b0df-df6b9ac38af1"],"parameters":["102cb20f-9f88-4471-89b0-bdd746912710"],"requestBody":"c47b870b-4b61-4349-9604-e449187a9518","responses":{"201":"22fbeedc-e91e-427c-a278-f2afa2d339d0","400":"c17c3b04-52a3-4f38-83d6-585df4b41985","401":"c065bc1b-49ec-4d5b-90e9-e387ca5fc665","404":"66db549d-fc34-4d72-b796-15b1e705a2b1","409":"a9d19f75-7c2d-4564-8106-452ebc7534dc","429":"1b09cae9-67d1-478d-a828-8080dc3226cf"},"method":"post","type":"path","servers":["15355b2c-94fb-418f-acf2-2e27904062bb"],"path":"/api/v1/webhooks","baseUrlOptions":["https://control.ergoly.ai"],"title":"Create a webhook","codeSamples":[],"requestExampleLanguages":["bash","javascript","python"],"requiredOnlyExamples":true,"requestExampleType":"generated","responseExampleType":"generated"},"dependencies":{"parameters":{"102cb20f-9f88-4471-89b0-bdd746912710":{"name":"Idempotency-Key","in":"header","required":false,"description":"Any unique string. A retry under the same key is answered from the first attempt's record, with `X-Idempotent-Replay: true`. The same key with a different body is a conflict.","schema":{"type":"string","description":"Any unique string.","isRequired":false,"uniqueKey":"","typeLabel":"string"}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workerId":{"type":"string","description":"The Worker whose agent takes each delivery's turn. Resolved under your organization.","isRequired":true,"uniqueKey":"workerId","typeLabel":"string"},"name":{"type":"string","description":"What this endpoint is called. 1–120 characters; the agent is told a delivery came from it.","isRequired":true,"uniqueKey":"name","typeLabel":"string"},"surfaceKind":{"type":"string","enum":["channel","dm"],"description":"A room, or a direct message with one person.","isRequired":true,"uniqueKey":"surfaceKind","typeLabel":"enum\u003cstring>"},"description":{"type":"string","description":"Free text for whoever maintains it. 500 characters or fewer.","uniqueKey":"description","typeLabel":"string"},"channelId":{"type":"string","description":"Required on `channel`. A channel already mapped to this Worker — an unmapped room, and a DM id, are both refused.","uniqueKey":"channelId","typeLabel":"string"},"slackUserId":{"type":"string","description":"Required on `dm`. The person the worker sends each result to.","uniqueKey":"slackUserId","typeLabel":"string"},"threading":{"type":"string","enum":["top_level","new_thread","same_thread"],"description":"Sets the run settings: `same_thread` keeps memory and runs events one at a time; the others overlap with a fresh conversation each. Absent is `top_level`.","uniqueKey":"threading","typeLabel":"enum\u003cstring>"},"rootText":{"type":"string","description":"Unused: stored, and nothing reads it. 500 characters or fewer.","uniqueKey":"rootText","typeLabel":"string"},"promptTemplate":{"type":"string","description":"What the agent is asked to do. 4000 characters or fewer. The payload is appended below it, or placed at `{{payload}}` when the template names that.","uniqueKey":"promptTemplate","typeLabel":"string"},"secretKind":{"type":"string","enum":["header","link"],"description":"`header` (absent) mints a `whsec_…` secret the sender puts in `Authorization: Bearer`. `link` mints a `whlnk_…` secret carried in the URL, for a sender that takes only a web address (Calendly, Cal.com), and answers `link` beside `secret`. A rotate without `link` turns a link webhook into a header one.","uniqueKey":"secretKind","typeLabel":"enum\u003cstring>"},"linkAcknowledged":{"type":"boolean","description":"Required, and `true`, with `secretKind: \"link\"`: you accept that the tool you paste the link into keeps a copy of it, and that a link carrying a secret is less safe than a secret sent in a header. Without it the call is a 400 and nothing is changed.","uniqueKey":"linkAcknowledged","typeLabel":"boolean"}},"required":["workerId","name","surfaceKind"],"additionalProperties":false,"uniqueKey":"","typeLabel":"object"},"example":{"workerId":"8f1c2d3e-9a4b-4c5d-8e6f-1a2b3c4d5e6f","name":"Deploy notifications","surfaceKind":"channel","channelId":"C0A1B2C3D4E"},"examples":{"Example":{"title":"Example","value":{"workerId":"8f1c2d3e-9a4b-4c5d-8e6f-1a2b3c4d5e6f","name":"Deploy notifications","surfaceKind":"channel","channelId":"C0A1B2C3D4E"}}},"exampleType":"examples"}},"exampleType":"examples"},"responses":{"22fbeedc-e91e-427c-a278-f2afa2d339d0":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"webhook":{"type":"object","description":"An inbound URL that starts a turn.","properties":{"id":{"type":"string","description":"The webhook id. It is also the URL segment deliveries are POSTed to.","isRequired":true,"uniqueKey":"data.webhook.id","typeLabel":"string"},"organizationId":{"type":"string","description":"Always your own organization.","isRequired":true,"uniqueKey":"data.webhook.organizationId","typeLabel":"string"},"workerId":{"type":"string","description":"The Worker whose agent takes the delivery's turn.","isRequired":true,"uniqueKey":"data.webhook.workerId","typeLabel":"string"},"clientId":{"oneOf":[{"type":"string","description":"The Client whose scope owns this webhook. Null on a core-scoped one, which is what a key creates. Where its deliveries run is `workClientId`.","isRequired":true,"uniqueKey":"data.webhook.clientId.oneOf.0","typeLabel":"string"},{"type":"null","description":"The Client whose scope owns this webhook. Null on a core-scoped one, which is what a key creates. Where its deliveries run is `workClientId`.","isRequired":true,"uniqueKey":"data.webhook.clientId.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"data.webhook.clientId","typeLabel":"string | null"},"workClientId":{"oneOf":[{"type":"string","description":"Null when the work is no one client's: an internal room, a DM, a task whose targets name several clients, or a revoked webhook, which has let go of its task (`taskId: null`). Otherwise the Client whose work each delivery is, read from its task: a webhook on a room mapped to a client runs on that client's agent.","isRequired":true,"uniqueKey":"data.webhook.workClientId.oneOf.0","typeLabel":"string"},{"type":"null","description":"Null when the work is no one client's: an internal room, a DM, a task whose targets name several clients, or a revoked webhook, which has let go of its task (`taskId: null`). Otherwise the Client whose work each delivery is, read from its task: a webhook on a room mapped to a client runs on that client's agent.","isRequired":true,"uniqueKey":"data.webhook.workClientId.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"data.webhook.workClientId","typeLabel":"string | null"},"name":{"type":"string","description":"What this endpoint is called. It is what the agent is told the delivery came from.","isRequired":true,"uniqueKey":"data.webhook.name","typeLabel":"string"},"description":{"oneOf":[{"type":"string","description":"Free text for whoever maintains it.","isRequired":true,"uniqueKey":"data.webhook.description.oneOf.0","typeLabel":"string"},{"type":"null","description":"Free text for whoever maintains it.","isRequired":true,"uniqueKey":"data.webhook.description.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"data.webhook.description","typeLabel":"string | null"},"url":{"type":"string","description":"Where to POST. Absolute, so you need no base URL of your own.","isRequired":true,"uniqueKey":"data.webhook.url","typeLabel":"string"},"surface":{"type":"object","description":"Where the worker posts each delivery's result.","properties":{"kind":{"type":"string","enum":["channel","dm"],"description":"A room, or a direct message with one person.","isRequired":true,"uniqueKey":"data.webhook.surface.kind","typeLabel":"enum\u003cstring>"},"channelId":{"oneOf":[{"type":"string","description":"The Slack channel id, on a `channel` webhook.","isRequired":true,"uniqueKey":"data.webhook.surface.channelId.oneOf.0","typeLabel":"string"},{"type":"null","description":"The Slack channel id, on a `channel` webhook.","isRequired":true,"uniqueKey":"data.webhook.surface.channelId.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"data.webhook.surface.channelId","typeLabel":"string | null"},"slackUserId":{"oneOf":[{"type":"string","description":"The Slack user id, on a `dm` webhook.","isRequired":true,"uniqueKey":"data.webhook.surface.slackUserId.oneOf.0","typeLabel":"string"},{"type":"null","description":"The Slack user id, on a `dm` webhook.","isRequired":true,"uniqueKey":"data.webhook.surface.slackUserId.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"data.webhook.surface.slackUserId","typeLabel":"string | null"}},"required":["kind","channelId","slackUserId"],"additionalProperties":false,"isRequired":true,"uniqueKey":"data.webhook.surface","typeLabel":"object"},"threading":{"type":"string","enum":["top_level","new_thread","same_thread"],"description":"The older way to set `runMode` and `keepMemory`. `top_level` and `new_thread` behave alike: events overlap, each run with its own conversation. `same_thread` runs events one at a time on the task's one shared conversation; it is not one Slack thread.","isRequired":true,"uniqueKey":"data.webhook.threading","typeLabel":"enum\u003cstring>"},"taskId":{"oneOf":[{"type":"string","description":"The task each delivery starts a run on. Its destination is where results go; null once a revoke has let go of it.","isRequired":true,"uniqueKey":"data.webhook.taskId.oneOf.0","typeLabel":"string"},{"type":"null","description":"The task each delivery starts a run on. Its destination is where results go; null once a revoke has let go of it.","isRequired":true,"uniqueKey":"data.webhook.taskId.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"data.webhook.taskId","typeLabel":"string | null"},"runMode":{"type":"string","enum":["overlap","one_at_a_time"],"description":"`overlap` runs events side by side, each with its own conversation. `one_at_a_time` runs them in turn on the task's shared conversation.","isRequired":true,"uniqueKey":"data.webhook.runMode","typeLabel":"enum\u003cstring>"},"keepMemory":{"type":"boolean","description":"True when every event run shares the task's one conversation, so a later event remembers an earlier one. Implies `one_at_a_time`.","isRequired":true,"uniqueKey":"data.webhook.keepMemory","typeLabel":"boolean"},"threadTs":{"oneOf":[{"type":"string","description":"Unused: nothing reads or writes it.","isRequired":true,"uniqueKey":"data.webhook.threadTs.oneOf.0","typeLabel":"string"},{"type":"null","description":"Unused: nothing reads or writes it.","isRequired":true,"uniqueKey":"data.webhook.threadTs.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"data.webhook.threadTs","typeLabel":"string | null"},"rootText":{"oneOf":[{"type":"string","description":"Unused: stored, and nothing reads it.","isRequired":true,"uniqueKey":"data.webhook.rootText.oneOf.0","typeLabel":"string"},{"type":"null","description":"Unused: stored, and nothing reads it.","isRequired":true,"uniqueKey":"data.webhook.rootText.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"data.webhook.rootText","typeLabel":"string | null"},"promptTemplate":{"oneOf":[{"type":"string","description":"What the agent is asked to do, with the payload appended below it — or placed at `{{payload}}` when the template names that. Null uses the built-in wording.","isRequired":true,"uniqueKey":"data.webhook.promptTemplate.oneOf.0","typeLabel":"string"},{"type":"null","description":"What the agent is asked to do, with the payload appended below it — or placed at `{{payload}}` when the template names that. Null uses the built-in wording.","isRequired":true,"uniqueKey":"data.webhook.promptTemplate.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"data.webhook.promptTemplate","typeLabel":"string | null"},"enabled":{"type":"boolean","description":"False once it is disabled or revoked. Every delivery to a disabled endpoint answers 410.","isRequired":true,"uniqueKey":"data.webhook.enabled","typeLabel":"boolean"},"createdBy":{"type":"string","enum":["operator","ework","api"],"description":"Which surface minted it. Audit only; nothing behaves differently.","isRequired":true,"uniqueKey":"data.webhook.createdBy","typeLabel":"enum\u003cstring>"},"lastDeliveredAt":{"oneOf":[{"type":"string","format":"date-time","description":"When it last accepted a delivery.","isRequired":true,"uniqueKey":"data.webhook.lastDeliveredAt.oneOf.0","typeLabel":"string\u003cdate-time>"},{"type":"null","format":"date-time","description":"When it last accepted a delivery.","isRequired":true,"uniqueKey":"data.webhook.lastDeliveredAt.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"data.webhook.lastDeliveredAt","typeLabel":"string\u003cdate-time> | null"},"revokedAt":{"oneOf":[{"type":"string","format":"date-time","description":"When it was retired. A revoke is a one-way door.","isRequired":true,"uniqueKey":"data.webhook.revokedAt.oneOf.0","typeLabel":"string\u003cdate-time>"},{"type":"null","format":"date-time","description":"When it was retired. A revoke is a one-way door.","isRequired":true,"uniqueKey":"data.webhook.revokedAt.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"data.webhook.revokedAt","typeLabel":"string\u003cdate-time> | null"},"createdAt":{"type":"string","format":"date-time","description":"When it was created.","isRequired":true,"uniqueKey":"data.webhook.createdAt","typeLabel":"string\u003cdate-time>"},"updatedAt":{"type":"string","format":"date-time","description":"When it was last changed.","isRequired":true,"uniqueKey":"data.webhook.updatedAt","typeLabel":"string\u003cdate-time>"}},"required":["id","organizationId","workerId","clientId","workClientId","name","description","url","surface","threading","taskId","runMode","keepMemory","threadTs","rootText","promptTemplate","enabled","createdBy","lastDeliveredAt","revokedAt","createdAt","updatedAt"],"additionalProperties":false,"isRequired":true,"uniqueKey":"data.webhook","typeLabel":"object"},"url":{"type":"string","description":"Where to POST.","isRequired":true,"uniqueKey":"data.url","typeLabel":"string"},"secret":{"type":"string","description":"The delivery credential, SHOWN ONCE. A `whsec_…` secret goes as `Authorization: Bearer \u003csecret>` on every POST; a `whlnk_…` secret (link mode) rides in `link`. It is stored hashed, so this is the only time it can be read — store it now, or rotate.","isRequired":true,"uniqueKey":"data.secret","typeLabel":"string"},"link":{"type":"string","description":"Link mode only, and absent otherwise: the URL with the secret in it (`?token=whlnk_…`), for a sender that takes a web address and cannot set a header. SHOWN ONCE. The link is the credential: treat it like a password.","uniqueKey":"data.link","typeLabel":"string"}},"required":["webhook","url","secret"],"additionalProperties":false,"isRequired":true,"uniqueKey":"data","typeLabel":"object"}},"required":["data"],"additionalProperties":false,"uniqueKey":"","typeLabel":"object"},"example":{"data":{"webhook":{"id":"f2e1d0c9-b8a7-4655-9243-1c0b9a8d7e6f","organizationId":"0d4c9f2e-4b8a-4a5b-9e21-6f9c2a1b7d30","workerId":"8f1c2d3e-9a4b-4c5d-8e6f-1a2b3c4d5e6f","clientId":null,"workClientId":"c1a2b3c4-d5e6-4f70-8912-3a4b5c6d7e8f","name":"Deploy notifications","description":"Our CI posts here when a release finishes.","url":"https://api.ergoly.ai/api/hooks/f2e1d0c9-b8a7-4655-9243-1c0b9a8d7e6f","surface":{"kind":"channel","channelId":"C0A1B2C3D4E","slackUserId":null},"threading":"top_level","taskId":"5d6e7f80-91a2-4b3c-8d4e-5f60718293a4","runMode":"overlap","keepMemory":false,"threadTs":null,"rootText":null,"promptTemplate":null,"enabled":true,"createdBy":"api","lastDeliveredAt":"2026-03-04T11:02:31.000Z","revokedAt":null,"createdAt":"2026-02-28T14:10:00.000Z","updatedAt":"2026-03-04T11:02:31.000Z"},"url":"https://api.ergoly.ai/api/hooks/f2e1d0c9-b8a7-4655-9243-1c0b9a8d7e6f","secret":"whsec_9f2c1b7a4e6d08135a29c4b7e0d6f381a2c5b9e04d7f1638a2b4c6d8e0f1a3b5"}},"examples":{"Example":{"title":"Example","value":{"data":{"webhook":{"id":"f2e1d0c9-b8a7-4655-9243-1c0b9a8d7e6f","organizationId":"0d4c9f2e-4b8a-4a5b-9e21-6f9c2a1b7d30","workerId":"8f1c2d3e-9a4b-4c5d-8e6f-1a2b3c4d5e6f","clientId":null,"workClientId":"c1a2b3c4-d5e6-4f70-8912-3a4b5c6d7e8f","name":"Deploy notifications","description":"Our CI posts here when a release finishes.","url":"https://api.ergoly.ai/api/hooks/f2e1d0c9-b8a7-4655-9243-1c0b9a8d7e6f","surface":{"kind":"channel","channelId":"C0A1B2C3D4E","slackUserId":null},"threading":"top_level","taskId":"5d6e7f80-91a2-4b3c-8d4e-5f60718293a4","runMode":"overlap","keepMemory":false,"threadTs":null,"rootText":null,"promptTemplate":null,"enabled":true,"createdBy":"api","lastDeliveredAt":"2026-03-04T11:02:31.000Z","revokedAt":null,"createdAt":"2026-02-28T14:10:00.000Z","updatedAt":"2026-03-04T11:02:31.000Z"},"url":"https://api.ergoly.ai/api/hooks/f2e1d0c9-b8a7-4655-9243-1c0b9a8d7e6f","secret":"whsec_9f2c1b7a4e6d08135a29c4b7e0d6f381a2c5b9e04d7f1638a2b4c6d8e0f1a3b5"}}}},"exampleType":"examples"}},"exampleType":"examples"},"c17c3b04-52a3-4f38-83d6-585df4b41985":{"description":"`invalid_request`","content":{"application/json":{"schema":{"type":"object","description":"The one error shape. Every refusal in this namespace has it.","properties":{"error":{"type":"object","description":"The refusal.","properties":{"code":{"type":"string","enum":["unauthorized","not_found","invalid_request","conflict","quota_exceeded","rate_limited","upstream_error","gone"],"description":"The machine-stable half. Branch on this, never on `message`.","isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","description":"Prose for a human reading a terminal.","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"docs":{"type":"string","description":"Where to learn how to authenticate. Present on `unauthorized` and on nothing else — it is the one refusal a caller can reach with no credential at all, so it is the one that has to say where the way in is.","uniqueKey":"error.docs","typeLabel":"string"}},"required":["code","message"],"additionalProperties":false,"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"additionalProperties":false,"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"error":{"code":"unauthorized","message":"\u003cstring>","docs":"\u003cstring>"}}}},"exampleType":"generated"}},"exampleType":"generated"},"c065bc1b-49ec-4d5b-90e9-e387ca5fc665":{"description":"`unauthorized`","content":{"application/json":{"schema":{"type":"object","description":"The one error shape. Every refusal in this namespace has it.","properties":{"error":{"type":"object","description":"The refusal.","properties":{"code":{"type":"string","enum":["unauthorized","not_found","invalid_request","conflict","quota_exceeded","rate_limited","upstream_error","gone"],"description":"The machine-stable half. Branch on this, never on `message`.","isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","description":"Prose for a human reading a terminal.","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"docs":{"type":"string","description":"Where to learn how to authenticate. Present on `unauthorized` and on nothing else — it is the one refusal a caller can reach with no credential at all, so it is the one that has to say where the way in is.","uniqueKey":"error.docs","typeLabel":"string"}},"required":["code","message"],"additionalProperties":false,"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"additionalProperties":false,"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"error":{"code":"unauthorized","message":"\u003cstring>","docs":"\u003cstring>"}}}},"exampleType":"generated"}},"exampleType":"generated"},"66db549d-fc34-4d72-b796-15b1e705a2b1":{"description":"`not_found`","content":{"application/json":{"schema":{"type":"object","description":"The one error shape. Every refusal in this namespace has it.","properties":{"error":{"type":"object","description":"The refusal.","properties":{"code":{"type":"string","enum":["unauthorized","not_found","invalid_request","conflict","quota_exceeded","rate_limited","upstream_error","gone"],"description":"The machine-stable half. Branch on this, never on `message`.","isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","description":"Prose for a human reading a terminal.","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"docs":{"type":"string","description":"Where to learn how to authenticate. Present on `unauthorized` and on nothing else — it is the one refusal a caller can reach with no credential at all, so it is the one that has to say where the way in is.","uniqueKey":"error.docs","typeLabel":"string"}},"required":["code","message"],"additionalProperties":false,"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"additionalProperties":false,"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"error":{"code":"unauthorized","message":"\u003cstring>","docs":"\u003cstring>"}}}},"exampleType":"generated"}},"exampleType":"generated"},"a9d19f75-7c2d-4564-8106-452ebc7534dc":{"description":"`conflict`","content":{"application/json":{"schema":{"type":"object","description":"The one error shape. Every refusal in this namespace has it.","properties":{"error":{"type":"object","description":"The refusal.","properties":{"code":{"type":"string","enum":["unauthorized","not_found","invalid_request","conflict","quota_exceeded","rate_limited","upstream_error","gone"],"description":"The machine-stable half. Branch on this, never on `message`.","isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","description":"Prose for a human reading a terminal.","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"docs":{"type":"string","description":"Where to learn how to authenticate. Present on `unauthorized` and on nothing else — it is the one refusal a caller can reach with no credential at all, so it is the one that has to say where the way in is.","uniqueKey":"error.docs","typeLabel":"string"}},"required":["code","message"],"additionalProperties":false,"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"additionalProperties":false,"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"error":{"code":"unauthorized","message":"\u003cstring>","docs":"\u003cstring>"}}}},"exampleType":"generated"}},"exampleType":"generated"},"1b09cae9-67d1-478d-a828-8080dc3226cf":{"description":"`rate_limited`","content":{"application/json":{"schema":{"type":"object","description":"The one error shape. Every refusal in this namespace has it.","properties":{"error":{"type":"object","description":"The refusal.","properties":{"code":{"type":"string","enum":["unauthorized","not_found","invalid_request","conflict","quota_exceeded","rate_limited","upstream_error","gone"],"description":"The machine-stable half. Branch on this, never on `message`.","isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","description":"Prose for a human reading a terminal.","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"docs":{"type":"string","description":"Where to learn how to authenticate. Present on `unauthorized` and on nothing else — it is the one refusal a caller can reach with no credential at all, so it is the one that has to say where the way in is.","uniqueKey":"error.docs","typeLabel":"string"}},"required":["code","message"],"additionalProperties":false,"isRequired":true,"uniqueKey":"error","typeLabel":"object"}},"required":["error"],"additionalProperties":false,"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"error":{"code":"unauthorized","message":"\u003cstring>","docs":"\u003cstring>"}}}},"exampleType":"generated"}},"exampleType":"generated"}},"security":{"59622cc5-91f9-4e7c-b0df-df6b9ac38af1":{"orgApiKey":{"type":"http","scheme":"bearer","description":"An organization-scoped API key, minted in control under Settings → API keys. Every failure to authenticate answers one identical 401: \"Provide a valid organization-scoped API key or an active session.\" Each operation names the one scope it is filed under, `\u003cresource>:\u003cread|write>`, where the resource is the first path segment after `/api/v1/`; a key minted today carries all 22 of them. Scopes are RECORDED — on the key and on every audit row — and are not yet enforced: no request is refused for want of one.","scopes":["webhooks:write"],"schemeName":"orgApiKey"}}},"servers":{"15355b2c-94fb-418f-acf2-2e27904062bb":{"url":"https://control.ergoly.ai"}},"processedSecurityOptions":[{"schemes":[{"scheme":{"type":"http","scheme":"bearer","description":"An organization-scoped API key, minted in control under Settings → API keys. Every failure to authenticate answers one identical 401: \"Provide a valid organization-scoped API key or an active session.\" Each operation names the one scope it is filed under, `\u003cresource>:\u003cread|write>`, where the resource is the first path segment after `/api/v1/`; a key minted today carries all 22 of them. Scopes are RECORDED — on the key and on every audit row — and are not yet enforced: no request is refused for want of one.","scopes":["webhooks:write"],"schemeName":"orgApiKey"},"schema":{"title":"Bearer Auth","type":"string","isRequired":true,"description":"An organization-scoped API key, minted in control under Settings → API keys. Every failure to authenticate answers one identical 401: \"Provide a valid organization-scoped API key or an active session.\" Each operation names the one scope it is filed under, `\u003cresource>:\u003cread|write>`, where the resource is the first path segment after `/api/v1/`; a key minted today carries all 22 of them. Scopes are RECORDED — on the key and on every audit row — and are not yet enforced: no request is refused for want of one.","format":"bearer","typeLabel":"string\u003cbearer>","deprecated":false},"schemeName":"orgApiKey","name":"Authorization"}],"title":"orgApiKey"}]},"originalFileLocation":"openapi.json"},"subdomain":"ergoly","siteName":"Ergoly","title":"Create a webhook - Ergoly","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-11-09T02:24:49.003Z","originalFileLocation":"api-reference/webhooks/create-a-webhook.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Returns the URL to POST to and the secret to send with it. surfaceKind: \u0026quot;channel\u0026quot; needs a channelId already mapped to this Worker — an unmapped room, and a DM id, are both refused; \u0026quot;dm\u0026quot; needs the slackUserId of the person. On a room mapped to a client, workClientId names that client. For a sender that cannot set a header, secretKind: \u0026quot;link\u0026quot; with linkAcknowledged: true answers a link with the secret in it. The secret in the response, and the link in link mode, are shown once and the secret is stored hashed. Nothing can read them back — if you lose them, your only option is to rotate, which breaks whatever is already using the old one. Treat a link like a password.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Ergoly\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/ergoly/OjkmtN-S1YevUC4M/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/ergoly/OjkmtN-S1YevUC4M/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/ergoly/OjkmtN-S1YevUC4M/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/ergoly/OjkmtN-S1YevUC4M/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/ergoly/OjkmtN-S1YevUC4M/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/ergoly/OjkmtN-S1YevUC4M/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/ergoly/OjkmtN-S1YevUC4M/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/ergoly/OjkmtN-S1YevUC4M/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/ergoly/OjkmtN-S1YevUC4M/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Create a webhook - Ergoly\">\u003cmeta data-mint-head property=\"og:description\" content=\"Returns the URL to POST to and the secret to send with it. surfaceKind: \u0026quot;channel\u0026quot; needs a channelId already mapped to this Worker — an unmapped room, and a DM id, are both refused; \u0026quot;dm\u0026quot; needs the slackUserId of the person. On a room mapped to a client, workClientId names that client. For a sender that cannot set a header, secretKind: \u0026quot;link\u0026quot; with linkAcknowledged: true answers a link with the secret in it. The secret in the response, and the link in link mode, are shown once and the secret is stored hashed. Nothing can read them back — if you lose them, your only option is to rotate, which breaks whatever is already using the old one. Treat a link like a password.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Ergoly\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.ergoly.ai/api-reference/webhooks/create-a-webhook\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://ergoly.mintlify.site/_mintlify/api/og/v2?division=Webhooks\u0026amp;title=Create+a+webhook\u0026amp;description=Returns+the+URL+to+POST+to+and+the+secret+to+send+with+it.+%60surfaceKind%3A+%22channel%22%60+needs+a+%60channelId%60+already+mapped+to+this+Worker+%E2%80%94+an+unmapped+room%2C+and+a+\u0026amp;theme=46f41713e7d152b6296bdf32\u0026amp;signature=d6c2d78d1b92e545e7dd0981d07dfa2dc7b2ef9d849940cb3a8cdba1b30f273e\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Create a webhook - Ergoly\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Returns the URL to POST to and the secret to send with it. surfaceKind: \u0026quot;channel\u0026quot; needs a channelId already mapped to this Worker — an unmapped room, and a DM id, are both refused; \u0026quot;dm\u0026quot; needs the slackUserId of the person. On a room mapped to a client, workClientId names that client. For a sender that cannot set a header, secretKind: \u0026quot;link\u0026quot; with linkAcknowledged: true answers a link with the secret in it. The secret in the response, and the link in link mode, are shown once and the secret is stored hashed. Nothing can read them back — if you lose them, your only option is to rotate, which breaks whatever is already using the old one. Treat a link like a password.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://ergoly.mintlify.site/_mintlify/api/og/v2?division=Webhooks\u0026amp;title=Create+a+webhook\u0026amp;description=Returns+the+URL+to+POST+to+and+the+secret+to+send+with+it.+%60surfaceKind%3A+%22channel%22%60+needs+a+%60channelId%60+already+mapped+to+this+Worker+%E2%80%94+an+unmapped+room%2C+and+a+\u0026amp;theme=46f41713e7d152b6296bdf32\u0026amp;signature=d6c2d78d1b92e545e7dd0981d07dfa2dc7b2ef9d849940cb3a8cdba1b30f273e\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/ergoly/OjkmtN-S1YevUC4M/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Ergoly\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#079b9b\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.ergoly.ai/api-reference/webhooks/create-a-webhook\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/api-reference/webhooks/create-a-webhook.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.ergoly.ai/#organization\",\"name\":\"Ergoly\",\"url\":\"https://docs.ergoly.ai\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/ergoly/-drdYd6uXChmiNIn/logo/light.png?fit=max\u0026auto=format\u0026n=-drdYd6uXChmiNIn\u0026q=85\u0026s=a9084e9caaf8656a821bf02426e31c05\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.ergoly.ai#website\",\"name\":\"Ergoly\",\"url\":\"https://docs.ergoly.ai\",\"publisher\":{\"@id\":\"https://docs.ergoly.ai/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.ergoly.ai/api-reference/webhooks/create-a-webhook#webpage\",\"url\":\"https://docs.ergoly.ai/api-reference/webhooks/create-a-webhook\",\"name\":\"Create a webhook\",\"description\":\"Returns the URL to POST to and the secret to send with it. surfaceKind: \\\"channel\\\" needs a channelId already mapped to this Worker — an unmapped room, and a DM id, are both refused; \\\"dm\\\" needs the slackUserId of the person. On a room mapped to a client, workClientId names that client. For a sender that cannot set a header, secretKind: \\\"link\\\" with linkAcknowledged: true answers a link with the secret in it. The secret in the response, and the link in link mode, are shown once and the secret is stored hashed. Nothing can read them back — if you lose them, your only option is to rotate, which breaks whatever is already using the old one. Treat a link like a password.\",\"dateModified\":\"2026-11-09T02:24:49.003Z\",\"isPartOf\":{\"@id\":\"https://docs.ergoly.ai#website\"},\"breadcrumb\":{\"@id\":\"https://docs.ergoly.ai/api-reference/webhooks/create-a-webhook#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.ergoly.ai/api-reference/webhooks/create-a-webhook#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Webhooks\",\"item\":\"https://docs.ergoly.ai/api-reference/webhooks/list-webhooks\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Create a webhook\",\"item\":\"https://docs.ergoly.ai/api-reference/webhooks/create-a-webhook\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://docs.ergoly.ai/api-reference/webhooks/create-a-webhook#apireference\",\"headline\":\"Create a webhook\",\"name\":\"Create a webhook\",\"description\":\"Returns the URL to POST to and the secret to send with it. surfaceKind: \\\"channel\\\" needs a channelId already mapped to this Worker — an unmapped room, and a DM id, are both refused; \\\"dm\\\" needs the slackUserId of the person. On a room mapped to a client, workClientId names that client. For a sender that cannot set a header, secretKind: \\\"link\\\" with linkAcknowledged: true answers a link with the secret in it. The secret in the response, and the link in link mode, are shown once and the secret is stored hashed. Nothing can read them back — if you lose them, your only option is to rotate, which breaks whatever is already using the old one. Treat a link like a password.\",\"url\":\"https://docs.ergoly.ai/api-reference/webhooks/create-a-webhook\",\"mainEntityOfPage\":{\"@id\":\"https://docs.ergoly.ai/api-reference/webhooks/create-a-webhook#webpage\"},\"dateModified\":\"2026-11-09T02:24:49.003Z\",\"publisher\":{\"@id\":\"https://docs.ergoly.ai/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.ergoly.ai#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Ergoly\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Ergoly","nav":{"global":null,"tabs":[{"tab":"Docs","icon":"book-open","pages":[{"title":"Docs","href":""}]},{"tab":"Changelog","icon":"sparkles","pages":[{"title":"Changelog","href":"/changelog"}]},{"tab":"API","icon":"user-robot","groups":[{"group":"Getting started","pages":[{"title":"Introduction","href":"/api-reference/introduction"},{"title":"The API","href":"/technical/api"}]},{"group":"Company","pages":[{"title":"Get your company","deprecated":null,"version":null,"openapi":"/openapi.json get /api/v1/organization","href":"/api-reference/organization/get-your-company"},{"title":"List chart placements","deprecated":null,"version":null,"openapi":"/openapi.json get /api/v1/company/placements","href":"/api-reference/workers/list-chart-placements"},{"title":"Get the activity feed","deprecated":null,"version":null,"openapi":"/openapi.json get /api/v1/activity","href":"/api-reference/activity/get-the-activity-feed"},{"title":"Get usage","deprecated":null,"version":null,"openapi":"/openapi.json get /api/v1/usage","href":"/api-reference/usage/get-usage"}]},{"group":"Workers","pages":[{"title":"List workers","deprecated":null,"version":null,"openapi":"/openapi.json get /api/v1/workers","href":"/api-reference/workers/list-workers"},{"title":"Create a worker","deprecated":null,"version":null,"openapi":"/openapi.json post /api/v1/workers","href":"/api-reference/workers/create-a-worker"},{"title":"Get the current worker","deprecated":null,"version":null,"openapi":"/openapi.json get /api/v1/workers/me","href":"/api-reference/workers/get-the-current-worker"},{"title":"Get a worker","deprecated":null,"version":null,"openapi":"/openapi.json get /api/v1/workers/{id}","href":"/api-reference/workers/get-a-worker"},{"title":"Update a worker","deprecated":null,"version":null,"openapi":"/openapi.json patch /api/v1/workers/{id}","href":"/api-reference/workers/update-a-worker"},{"title":"Delete a worker","deprecated":null,"version":null,"openapi":"/openapi.json delete /api/v1/workers/{id}","href":"/api-reference/workers/delete-a-worker"},{"group":"Provisioning","pages":[{"title":"Retry provisioning","deprecated":null,"version":null,"openapi":"/openapi.json post /api/v1/workers/{id}/retry","href":"/api-reference/workers/retry-provisioning"},{"title":"Stop a worker","deprecated":null,"version":null,"openapi":"/openapi.json post /api/v1/workers/{id}/stop","href":"/api-reference/workers/stop-a-worker"},{"title":"Get a provisioning job","deprecated":null,"version":null,"openapi":"/openapi.json get /api/v1/jobs/{id}","href":"/api-reference/jobs/get-a-provisioning-job"}]},{"group":"Copies (eworks)","pages":[{"title":"List a worker's copies","deprecated":null,"version":null,"openapi":"/openapi.json get /api/v1/workers/{id}/eworks","href":"/api-reference/eworks/list-a-workers-copies"},{"title":"Get a copy","deprecated":null,"version":null,"openapi":"/openapi.json get /api/v1/eworks/{id}","href":"/api-reference/eworks/get-a-copy"}]},{"group":"Memory","pages":[{"title":"Read a memory tier","deprecated":null,"version":null,"openapi":"/openapi.json get /api/v1/eworks/{id}/memory","href":"/api-reference/memory/read-a-memory-tier"},{"title":"Write a file","deprecated":null,"version":null,"openapi":"/openapi.json put /api/v1/eworks/{id}/memory","href":"/api-reference/memory/write-a-file"},{"title":"Write several files","deprecated":null,"version":null,"openapi":"/openapi.json post /api/v1/eworks/{id}/memory","href":"/api-reference/memory/write-several-files"},{"title":"Delete a file or folder","deprecated":null,"version":null,"openapi":"/openapi.json delete /api/v1/eworks/{id}/memory","href":"/api-reference/memory/delete-a-file-or-folder"}]}]},{"group":"Clients","pages":[{"title":"List clients","deprecated":null,"version":null,"openapi":"/openapi.json get /api/v1/clients","href":"/api-reference/clients/list-clients"},{"title":"Create a client","deprecated":null,"version":null,"openapi":"/openapi.json post /api/v1/clients","href":"/api-reference/clients/create-a-client"},{"title":"Get a client","deprecated":null,"version":null,"openapi":"/openapi.json get /api/v1/clients/{id}","href":"/api-reference/clients/get-a-client"},{"title":"Update a client","deprecated":null,"version":null,"openapi":"/openapi.json patch /api/v1/clients/{id}","href":"/api-reference/clients/update-a-client"},{"title":"Assign a client to a worker","deprecated":null,"version":null,"openapi":"/openapi.json post /api/v1/workers/{id}/clients","href":"/api-reference/clients/assign-a-client-to-a-worker"}]},{"group":"Channels","pages":[{"title":"List Slack channels","deprecated":null,"version":null,"openapi":"/openapi.json get /api/v1/channels","href":"/api-reference/channels/list-slack-channels"},{"title":"Create a Slack channel","deprecated":null,"version":null,"openapi":"/openapi.json post /api/v1/channels","href":"/api-reference/channels/create-a-slack-channel"},{"group":"Channel mappings","pages":[{"title":"List channel mappings","deprecated":null,"version":null,"openapi":"/openapi.json get /api/v1/workers/{id}/channels","href":"/api-reference/channels/list-channel-mappings"},{"title":"Map a channel","deprecated":null,"version":null,"openapi":"/openapi.json post /api/v1/workers/{id}/channels","href":"/api-reference/channels/map-a-channel"},{"title":"Classify a channel","deprecated":null,"version":null,"openapi":"/openapi.json patch /api/v1/workers/{id}/channels/{channel}","href":"/api-reference/channels/classify-a-channel"},{"title":"Unmap a channel","deprecated":null,"version":null,"openapi":"/openapi.json delete /api/v1/workers/{id}/channels/{channel}","href":"/api-reference/channels/unmap-a-channel"},{"title":"Invite a worker to a channel","deprecated":null,"version":null,"openapi":"/openapi.json post /api/v1/workers/{id}/channels/{channel}/invite","href":"/api-reference/channels/invite-a-worker-to-a-channel"}]}]},{"group":"Tasks","pages":[{"title":"List tasks","deprecated":null,"version":null,"openapi":"/openapi.json get /api/v1/tasks","href":"/api-reference/tasks/list-tasks"},{"title":"Create a task","deprecated":null,"version":null,"openapi":"/openapi.json post /api/v1/tasks","href":"/api-reference/tasks/create-a-task"},{"title":"Get a task","deprecated":null,"version":null,"openapi":"/openapi.json get /api/v1/tasks/{id}","href":"/api-reference/tasks/get-a-task"},{"title":"Hand off a task","deprecated":null,"version":null,"openapi":"/openapi.json post /api/v1/tasks/{id}/handoff","href":"/api-reference/tasks/hand-off-a-task"},{"title":"Comment on a task","deprecated":null,"version":null,"openapi":"/openapi.json post /api/v1/tasks/{id}/comments","href":"/api-reference/tasks/comment-on-a-task"},{"title":"Change a task's state","deprecated":null,"version":null,"openapi":"/openapi.json post /api/v1/tasks/{id}/state","href":"/api-reference/tasks/change-a-tasks-state"},{"group":"Scheduled jobs (routines)","pages":[{"title":"Update a scheduled job","deprecated":null,"version":null,"openapi":"/openapi.json patch /api/v1/tasks/{id}","href":"/api-reference/tasks/update-a-scheduled-job"},{"title":"Cancel a scheduled job","deprecated":null,"version":null,"openapi":"/openapi.json delete /api/v1/tasks/{id}","href":"/api-reference/tasks/cancel-a-scheduled-job"},{"title":"List a job's runs","deprecated":null,"version":null,"openapi":"/openapi.json get /api/v1/tasks/{id}/runs","href":"/api-reference/tasks/list-a-jobs-runs"},{"title":"Add a target","deprecated":null,"version":null,"openapi":"/openapi.json post /api/v1/tasks/{id}/targets","href":"/api-reference/tasks/add-a-target"},{"title":"Remove a target","deprecated":null,"version":null,"openapi":"/openapi.json delete /api/v1/tasks/{id}/targets/{targetId}","href":"/api-reference/tasks/remove-a-target"}]}]},{"group":"Webhooks","pages":[{"title":"List webhooks","description":"Every inbound endpoint your organization has, revoked ones included — a retired webhook keeps its row so its delivery history stays readable, and `enabled: false` beside a `revokedAt` is what says which. No response here carries a secret. `?workerId=` narrows to one Worker.","deprecated":null,"version":null,"openapi":"/openapi.json get /api/v1/webhooks","href":"/api-reference/webhooks/list-webhooks"},{"title":"Create a webhook","deprecated":null,"version":null,"openapi":"/openapi.json post /api/v1/webhooks","href":"/api-reference/webhooks/create-a-webhook"},{"title":"Get a webhook","description":"The endpoint's configuration and its URL. Never its secret: the row holds a hash, so there is nothing here to return.","deprecated":null,"version":null,"openapi":"/openapi.json get /api/v1/webhooks/{id}","href":"/api-reference/webhooks/get-a-webhook"},{"title":"Update a webhook","deprecated":null,"version":null,"openapi":"/openapi.json patch /api/v1/webhooks/{id}","href":"/api-reference/webhooks/update-a-webhook"},{"title":"Revoke a webhook","deprecated":null,"version":null,"openapi":"/openapi.json delete /api/v1/webhooks/{id}","href":"/api-reference/webhooks/revoke-a-webhook"},{"title":"Rotate a webhook secret","deprecated":null,"version":null,"openapi":"/openapi.json post /api/v1/webhooks/{id}/rotate","href":"/api-reference/webhooks/rotate-a-webhook-secret"},{"title":"List deliveries","deprecated":null,"version":null,"openapi":"/openapi.json get /api/v1/webhooks/{id}/deliveries","href":"/api-reference/webhooks/list-deliveries"}]},{"group":"Connections","pages":[{"title":"List connections","deprecated":null,"version":null,"openapi":"/openapi.json get /api/v1/connections","href":"/api-reference/connections/list-connections"},{"title":"Create a connection","deprecated":null,"version":null,"openapi":"/openapi.json post /api/v1/connections","href":"/api-reference/connections/create-a-connection"},{"title":"Get a connection","deprecated":null,"version":null,"openapi":"/openapi.json get /api/v1/connections/{id}","href":"/api-reference/connections/get-a-connection"},{"title":"Update a connection","deprecated":null,"version":null,"openapi":"/openapi.json patch /api/v1/connections/{id}","href":"/api-reference/connections/update-a-connection"},{"title":"Delete a connection","deprecated":null,"version":null,"openapi":"/openapi.json delete /api/v1/connections/{id}","href":"/api-reference/connections/delete-a-connection"},{"title":"Rotate a connection","deprecated":null,"version":null,"openapi":"/openapi.json post /api/v1/connections/{id}/rotate","href":"/api-reference/connections/rotate-a-connection"},{"group":"Hosts","pages":[{"title":"List hosts","deprecated":null,"version":null,"openapi":"/openapi.json get /api/v1/connections/{id}/hosts","href":"/api-reference/connections/list-hosts"},{"title":"Add a host","deprecated":null,"version":null,"openapi":"/openapi.json post /api/v1/connections/{id}/hosts","href":"/api-reference/connections/add-a-host"},{"title":"Remove a host","deprecated":null,"version":null,"openapi":"/openapi.json delete /api/v1/connections/{id}/hosts/{host}","href":"/api-reference/connections/remove-a-host"}]},{"group":"Connected apps","pages":[{"title":"Get a connect URL","deprecated":null,"version":null,"openapi":"/openapi.json post /api/v1/connections/oauth/{provider}/connect-url","href":"/api-reference/connections/get-a-connect-url"},{"title":"Get a sign-in link","deprecated":null,"version":null,"openapi":"/openapi.json post /api/v1/connections/{id}/connect-url","href":"/api-reference/connections/get-a-sign-in-link"},{"title":"Add a placement","deprecated":null,"version":null,"openapi":"/openapi.json post /api/v1/connections/{id}/placements","href":"/api-reference/connections/add-a-placement"},{"title":"Remove a placement","deprecated":null,"version":null,"openapi":"/openapi.json delete /api/v1/connections/{id}/placements/{pid}","href":"/api-reference/connections/remove-a-placement"}]},{"group":"MCP servers","pages":[{"title":"Connect an MCP server","deprecated":null,"version":null,"openapi":"/openapi.json post /api/v1/connections/mcp","href":"/api-reference/connections/connect-an-mcp-server"},{"title":"Finish an MCP connection","deprecated":null,"version":null,"openapi":"/openapi.json post /api/v1/connections/mcp/{id}/finish","href":"/api-reference/connections/finish-an-mcp-connection"}]},{"group":"Provider apps","pages":[{"title":"Get a provider app","deprecated":null,"version":null,"openapi":"/openapi.json get /api/v1/connections/provider-apps/{provider}","href":"/api-reference/connections/get-a-provider-app"},{"title":"Set a provider app","deprecated":null,"version":null,"openapi":"/openapi.json put /api/v1/connections/provider-apps/{provider}","href":"/api-reference/connections/set-a-provider-app"},{"title":"Delete a provider app","deprecated":null,"version":null,"openapi":"/openapi.json delete /api/v1/connections/provider-apps/{provider}","href":"/api-reference/connections/delete-a-provider-app"}]},{"group":"Your own OAuth client","pages":[{"title":"Get your OAuth client","deprecated":null,"version":null,"openapi":"/openapi.json get /api/v1/oauth-apps/{app}","href":"/api-reference/connections/get-your-oauth-client"},{"title":"Set your OAuth client","deprecated":null,"version":null,"openapi":"/openapi.json put /api/v1/oauth-apps/{app}","href":"/api-reference/connections/set-your-oauth-client"},{"title":"Delete your OAuth client","deprecated":null,"version":null,"openapi":"/openapi.json delete /api/v1/oauth-apps/{app}","href":"/api-reference/connections/delete-your-oauth-client"}]}]}]}]},"basePath":"","title":"Create a webhook - Ergoly","buildId":"dpl_DTau1J5HqS9UTgVSDwGksstFWtPa","deploymentId":"dpl_DTau1J5HqS9UTgVSDwGksstFWtPa","dynamics":["10e4515597","c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["BannerMarkdown-Cj6eAYhz.js","dist-CdrJecqK.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","clsx-D-TRO5q5.js","html-void-elements-mCSPHezU.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","OpenApiReferenceProvider-5FCzAcfS.js","utils-SLtAG4EZ.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-2DZi8ZMu.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-D7J3nkzE.js","snippetPresets-D0Alv0AH.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","conditional-requirements-CFM0id0Q.js","ApiExamples-BI4qNJ2c.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-BD3uyr8j.js","shallow-D8iEBr5z.js","getApiPlaygroundDisplay-CgNP4lzR.js","CodeSnippet-CX-QHuMs.js","CodeSnippets-VlXE-ZUf.js","Page-D9ithiIZ.js","getPastedJson-DYNQkZ1M.js","icon-CzacdwOi.js","MethodPill-2JVqoYKi.js","DuplicateIcon-_xVXs-U8.js","createIcon-BRHrweLo.js","DynamicMarkdown-mQG_iQiE.js","SectionHeading-DMpJzv8f.js","axios-vUo_bRtp.js","Markdown-5FGIym-8.js","AssistantPageLink-CHlcWBLM.js"]}