Create a webhook
1
Open the channel's integrations
In the channel, open the ··· menu at the top and choose Integrations. You can also hover the channel in the
sidebar and choose Integrations from its ··· menu.
2
Add an incoming webhook
Select Add source, then Incoming webhook.
3
Name it
Give it a name, such as Deploys, and pick or upload an icon. Its posts show this name and icon.
4
Copy the URL
Select Create webhook, then Copy URL. Store it right away wherever it posts from, such as a CI secret. For a
Slack webhook field or GitHub, use Copy Slack URL or Copy GitHub URL instead.
Mantle shows the full URL only once. If you lose it, open the webhook and select Rotate URL to get a new one.
Send a message
Send aPOST request to the URL with a JSON body that has a text field. These examples read the URL from a
MANTLE_WEBHOOK_URL environment variable:
The request body
The body can be up to 64 KB. Other fields are ignored.
The answer
A post that went through answers200:
duplicate is true when the request repeated an earlier idempotency_key. With a thread_key, the answer also has
thread_root_message_id: the message the thread hangs from. Any other status is an error.
Format a message
text takes markdown: bold, italic, inline code, code blocks, links, lists, and quotes. A
single line break starts a new line, and emoji work as you type them.
Some things are left out, so a webhook can’t do more than a person’s message:
- Mentions don’t notify anyone. Writing a name keeps it as plain text.
- Images show as links. Mantle doesn’t load an image from another site, because loading it would tell that site who read the post.
- HTML shows as text.
- Only web addresses become links.
https://andhttp://links work; other kinds show as plain text.
Group updates in a thread
Add athread_key to keep related updates together, such as a build number or a ticket ID. The first post with a new
key goes to the channel. Each later post with the same key replies in that post’s thread.
- A key is 1 to 200 characters, and
Build-1042andbuild-1042are different keys. - Keys belong to the webhook, so two webhooks can use the same key without sharing a thread.
- If the thread’s first post is deleted, the next post with that key starts a new thread.
- Thread replies work like a person’s: they mark the channel unread and notify people who follow the thread.
Retry safely
Networks fail, and a request can reach Mantle even when its answer never comes back. Send anidempotency_key so a
retry doesn’t post twice: a repeat of a key answers with the first post and "duplicate": true, and posts nothing new.
Recipes
GitHub Actions
1
Add the URL as a secret
In the repository, go to Settings → Secrets and variables → Actions and add a secret named
MANTLE_WEBHOOK_URL.2
Post from a workflow
Add steps like these to a job. Both use the run’s ID as the thread key, so the result replies under the first post.
A script or cron job
Build the JSON withjq so quotes and line breaks in the message can’t break it:
Zapier, Make, and n8n
Add an HTTP request step to your automation and set it up like this. The labels differ a little between tools.
In Zapier, use Webhooks by Zapier → POST. In Make, use HTTP → Make a request. In n8n, use the HTTP Request
node.
Use it in a Slack webhook field
Many monitoring, uptime, and CI tools can post to a Slack incoming webhook. Give them the webhook’s URL with/slack on
the end, which Copy Slack URL copies, and they post here in Slack’s format:
- Formatting: Slack’s
*bold*,_italic_,~strike~, code, links, and quotes become Mantle’s. - Blocks, rich text, and attachments become one post: headers, sections and their fields, context, dividers, lists,
and quotes, with images and link buttons as links. When a message has blocks, they’re the post, and its
textis only Slack’s notification text. Menus, inputs, and buttons without a link are left out. - Mentions don’t notify anyone.
@here,@channel, people, and channels show as text. - The webhook keeps its own name and icon.
username,icon_url,icon_emoji, andchannelare ignored. - Emoji shortcodes such as
:white_check_mark:show as text. - Slack’s form body, with the JSON in a
payloadfield, works too.
200 ok as plain text, or Slack’s error code as plain text.
Anything else answers with the code from Errors, such as
429 rate_limited.
Use it with GitHub
GitHub can send a repository’s or an organization’s events straight to the webhook.1
Open the webhook settings
In the repository or organization, go to Settings → Webhooks and select Add webhook.
2
Paste the URL
In Payload URL, paste the webhook’s URL with
/github on the end. Copy GitHub URL copies it.3
Choose the content type
Choose
application/json. The form type works too.4
Leave the secret empty
The URL is the secret. Mantle can’t check one set here.
5
Choose the events
Select the events below, or send everything: events Mantle doesn’t post are accepted and dropped.
- Threads: a pull request’s events, reviews, and comments go into one thread, and an issue’s into another. The thread starts with the first of its events Mantle sees. Pushes, releases, and runs post in the channel.
- Excerpts: a comment, a review, or a new issue shows its first lines as text, and its link opens the rest.
- Redelivering an event from GitHub’s delivery log doesn’t post it twice.
- Tags and deleted branches post nothing.
- Bodies can be up to 1 MB.
- A wrong or rotated URL answers
404, so GitHub’s delivery log shows the event as failed.
What doesn’t work yet
- Other services’ own webhooks, such as Stripe’s or Sentry’s, send their own formats, and Mantle answers them
400 invalid_payload. If the service can post to a Slack webhook, use the Slack URL. Otherwise, send atextmessage from a CI step or an automation tool. - For Linear, Stripe, and Notion, add them from Add source in the same panel instead. Mantle posts their updates for you.
Errors
Every error answers with a JSON body:{ "ok": false, "error": "…", "message": "…" }. The Slack URL answers in
Slack’s way instead.
Retry only
429, 500, and 503, and send the same idempotency_key when you do. A wrong URL and a deleted webhook
answer the same 404, so nobody can use the answer to guess which webhooks exist.
Limits
Manage a webhook
Open the channel’s Integrations and select the webhook. Its page shows how many posts it made in the last 7 days and when it last posted. A webhook can be changed by the person who created it, or by a workspace admin or owner.- Rename it or change its icon with Edit. Its earlier posts show the new name and icon too.
- Rotate its URL if the URL leaked or got lost. The old URL stops working at once, and Mantle shows the new one once. Update it everywhere the webhook posts from.
- Delete it when nothing posts through it anymore. Anything still using its URL stops posting, and what it already posted stays in the channel.
When a webhook pauses
If the person who created a webhook leaves the workspace, the webhook pauses. It shows as Paused, and posts answer403 webhook_paused. A workspace admin or owner can resume it by rotating its URL. Then update the URL everywhere the
webhook posts from.
Keep the URL secret
The URL only lets someone post. It can’t read the channel or anything else in your workspace.Channels
Create channels and decide who can manage them.
Messages and threads
Follow a thread to hear about its replies.