Incoming webhooks
The simplest way for software to post: a secret URL that accepts one JSON body. No token, no code to
write. Any app with the incoming-webhook permission can have as many as it needs, each posting to one
channel. Create them under Manage → Installed apps → the app → Incoming webhooks; the URL is shown
once.
curl -X POST "https://app.example.com/api/public/apps/hooks/<secret>" \ -H 'Content-Type: application/json' \ -d '{"text": "Build passed"}'const response = await fetch("https://app.example.com/api/public/apps/hooks/<secret>", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ text: "Build passed" }),});// { ok: true, id: "<message id>" }console.log(await response.json());import jsonimport urllib.request
request = urllib.request.Request( "https://app.example.com/api/public/apps/hooks/<secret>", data=json.dumps({"text": "Build passed"}).encode(), headers={ "Content-Type": "application/json", # Name your app: some proxies refuse urllib's default User-Agent (Cloudflare answers 1010). "User-Agent": "my-app/1.0", }, method="POST",)with urllib.request.urlopen(request) as response: print(json.load(response)) # {"ok": true, "id": "<message id>"}Success is { "ok": true, "id": "<message id>" }. The message appears from the app, in the channel the
webhook was made for. The URL is the credential: it cannot call the Web API, and a token cannot post
through it. Replacing the URL stops the old one working.
The body
Section titled “The body”The same as Slack’s, so tools that already notify Slack can point at an Amedeus URL:
{"text": "…"}, Markdown, up to 8000 characters.- Or Slack’s
attachments: withouttext, each attachment’spretext,title,textandfields(onetitle: valueline per field) become the message. Slack’s<url|label>links become Markdown links.
A body with nothing to post is 400 invalid_arguments. Other fields (channel, username, colours,
blocks) are ignored: the channel and the author are fixed by the URL.
Limit: 60 messages a minute per URL.