Collaboration & Productivity

Mattermost Webhook Guide: Setup, Examples, and Integrations

J
James Eriksson
··13 min read
Complete guide to Mattermost webhooks: enable, create incoming and outgoing webhooks, secure with HTTPS and token rotation, integrate with GitHub, Grafana, n8n, Prometheus. Real examples and troubleshooting.
TL;DR
  • Incoming webhooks receive messages from external services; outgoing webhooks trigger external actions from Mattermost
  • Enable webhooks in System Console > Integrations, then create them via Main Menu > Integrations
  • Use HTTPS only, store webhook URLs in secrets managers, rotate tokens every 90 days, and audit unused webhooks
  • Integrate with GitHub (deployments), Grafana (alerts), n8n (workflows), and Prometheus (monitoring) via incoming webhook URLs
  • Common failures: wrong channel name, disabled webhooks in System Console, slow callback endpoints, and exposed tokens in Git

Mattermost webhooks let you pipe messages into channels automatically and trigger actions when events happen. Incoming webhooks push data into Mattermost from external services. Outgoing webhooks pull data out and call external services when team members speak. Learn how to set both up, secure them, and wire them to the tools your team already uses.

What Are Mattermost Webhooks?

Webhooks are HTTP callbacks that fire when something happens. In Mattermost, you have two directions: incoming (external service to Mattermost) and outgoing (Mattermost to external service). Incoming webhooks are simpler: you get a URL, you POST JSON to it, and a message lands in a channel. Outgoing webhooks fire when a trigger word appears or when a post matches a filter, then they call your callback URL with the post data.

Most teams use incoming webhooks for alerts: Grafana sends incident notifications, GitHub posts deployment status, Prometheus fires threshold alarms. Outgoing webhooks are less common but powerful: they let Mattermost trigger workflows in external systems without bots.

Compare this to slash commands (typed manually) and bots (service accounts that act autonomously). Webhooks are event-driven: they respond to external signals or post triggers without requiring a bot to be online. If you're tying Mattermost into your DevOps stack, webhooks are usually your first integration tool.

Mattermost is open source with 39.5K GitHub stars. The platform handles both self-hosted and cloud scenarios. If you're running Mattermost yourself, you control webhook enabling. If you use Mattermost Cloud, webhook support depends on your subscription tier.

How to Enable Webhooks in Mattermost

Before you create a webhook, an admin must enable webhooks in the System Console. Log in as System Admin and navigate to System Console > Integrations > Integration Management. You'll see toggles for Incoming Webhooks and Outgoing Webhooks. By default, both are disabled.

Toggle "Enable Incoming Webhooks" to allow team members to create incoming webhook URLs. Toggle "Enable Outgoing Webhooks" to allow creation of outgoing webhooks. You can also restrict who creates webhooks by setting permissions: "manage_webhooks" controls personal webhooks, "manage_others_webhooks" controls webhooks on behalf of others.

If you want tighter control, you can set "Lock Integrations to Team Admin" so only team admins create webhooks, not individual users. This is wise if your team is large or security-sensitive.

Note the System Console section also shows recent webhook activity. Use this to audit what's running. Old, unused webhooks pose a security risk: disable them and delete them if they are stale.

Creating Incoming Webhooks: Step-by-Step

Incoming webhooks are the workhorse of Mattermost integration. They accept POST requests and drop messages into a channel.

To create one: click Main Menu (top left) > Integrations > Incoming Webhooks > Create New Incoming Webhook. You'll see a form with these key fields:

  1. Title: Name your webhook (e.g., "GitHub Deployments"). This is internal, so be specific.
  2. Description: Document what it does and who owns it.
  3. Content Type: Default is "application/json". Keep it there.
  4. Channel: Select the channel where messages land. You can post to a different channel later by including channel ID in the JSON payload.
  5. Username: Customize the bot name (e.g., "Alerts Bot"). This appears above messages.
  6. Icon: Optional custom avatar URL.

Click "Create" and Mattermost will generate a unique webhook URL. Copy this URL and keep it private--anyone with it can post to your channel.

Test your webhook immediately with cURL, substituting your actual webhook URL:

curl -X POST [your-webhook-url] \
  -H 'Content-Type: application/json' \
  -d '{"text": "Hello from webhook"}'

If you get no error, check the channel. You should see a message from your bot. If it fails, verify the webhook URL is correct, HTTPS is enabled, and your firewall allows outbound traffic.

Incoming Webhook JSON Payload Examples

Mattermost incoming webhooks accept JSON payloads. The simplest payload has only text:

{
  "text": "Server cpu usage is at 95%"
}

But you can add much more. Here is a richer example:

{
  "username": "Alert Bot",
  "channel": "#alerts",
  "text": "Production Incident",
  "attachments": [
    {
      "fallback": "High error rate detected",
      "color": "#ff0000",
      "title": "Error Rate Spike",
      "text": "Error rate jumped to 5.2% in last 5 minutes",
      "fields": [
        {
          "title": "Service",
          "value": "API Gateway",
          "short": true
        },
        {
          "title": "Environment",
          "value": "Production",
          "short": true
        },
        {
          "title": "Threshold",
          "value": "2%",
          "short": true
        }
      ]
    }
  ]
}

This sends a message with username override, a red attachment, and structured fields. The color is a hex code; red is #ff0000, green is #22c55e, yellow is #eab308.

You can also send images, links, and markdown. Mattermost supports Slack-compatible attachment format, so Grafana, Datadog, and other tools that post to Slack webhooks often work here too.

Payload size limit is typically 4 MB. Keep payloads lean. Avoid sending full logs or raw data dumps; send summaries and links instead.

Mattermost ignores unknown fields, so if you send extra data it does not break the request.

Creating Outgoing Webhooks: Step-by-Step

Outgoing webhooks fire when a trigger word appears or when a post matches a filter. They call an external URL and send the post data. This is less common than incoming webhooks, but powerful for custom workflows.

Navigate to Main Menu > Integrations > Outgoing Webhooks > Create New Outgoing Webhook. You'll configure:

  1. Title: Name it (e.g., "Customer Support Alert").
  2. Description: Document what it does.
  3. Content Type: Choose "application/json".
  4. Trigger Words: Enter words that fire the webhook (e.g., "urgent", "critical"). If a post contains any trigger word, the webhook fires. Leave this blank to fire on all posts in a channel.
  5. Channel: Restrict to a specific channel, or leave blank to fire everywhere.
  6. Callback URL: The external service that receives the post data.
  7. Trigger When: Choose "A post is created" or "A post is created or updated".
  8. Show Public Option: If enabled, users can see this webhook's responses.

Click "Create". Mattermost will generate a token and show it once. Store it safely.

When a trigger word fires, Mattermost POSTs JSON to your callback URL. The payload includes post ID, user ID, channel, message text, and more. Your callback can respond with a message to post back to the channel, or return null for no response.

Example: you type "urgent: server down" in #ops. The webhook fires, sends post data to your callback endpoint, which parses the urgency level, pings an incident commander via SMS, and posts a confirmation to the channel.

Securing Your Webhooks

Webhooks are HTTP endpoints: exposure is a real risk. Here are hardened practices.

Use HTTPS only. Mattermost enforces HTTPS for webhook endpoints. No exceptions. If your callback URL is http-only, Mattermost rejects it. This prevents token interception.

Rotate tokens regularly. Outgoing webhooks include a token in the Authorization header. Treat it like a password. Rotate it every 90 days. If a token leaks, delete the webhook and create a new one.

Restrict webhook creation. In System Console > Integrations > Integration Management, set "Allow users to edit integrations they created" to control who can modify webhooks. Set "Restrict integrations to a specific team" if you have per-team isolation needs.

Avoid committing webhook URLs to Git. Webhook URLs are secrets. Store them in environment variables or secrets managers (HashiCorp Vault, AWS Secrets Manager, 1Password). If a URL is exposed in a public repository, regenerate it immediately.

Use separate webhooks per environment. Create one webhook for production, another for staging. If a staging token leaks, it does not compromise production.

Audit webhook activity. In System Console > Integrations > Integrations, view recent webhook activity. Look for unusual patterns: webhooks firing at odd hours, or to unexpected channels. Stale webhooks should be deleted.

Verify callback URL identity. When a webhook fires, your callback endpoint receives POST data. Verify the Authorization token in the header before processing. Do not assume the request came from Mattermost.

Integrating Webhooks with External Services

Here are common patterns with real tools.

GitHub Deployments to Mattermost:

GitHub can post deployment events to Mattermost. In your GitHub repository, go to Settings > Webhooks > Add Webhook. Set the Payload URL to your Mattermost incoming webhook URL. Select "Deployments" events. GitHub will POST deployment status to your Mattermost channel whenever you deploy.

GitHub webhook payloads include action, deployment ID, git reference, and environment. Your webhook can transform these into readable Mattermost messages with status and context.

Grafana Alerts to Mattermost:

Grafana supports webhook notifications. In Grafana, go to Alerting > Contact Points > Create New. Set the type to "Webhook". Enter your Mattermost incoming webhook URL. When a Grafana alert fires, it POSTs to your Mattermost webhook.

Grafana payloads include alert status (firing, resolved), metric name, and threshold info. You can format these nicely with Mattermost attachments:

{
  "attachments": [
    {
      "color": "#ff0000",
      "title": "Alert: CPU High",
      "text": "Server prod-01 cpu is 92%"
    }
  ]
}

n8n Workflow Trigger:

n8n is a workflow automation tool. You can use an outgoing Mattermost webhook to trigger an n8n workflow. Create an n8n HTTP webhook node and get its URL. In Mattermost, create an outgoing webhook pointing to the n8n URL. When someone posts a trigger word in Mattermost, the outgoing webhook calls n8n, which can then fetch data, transform it, and even post a response back to Mattermost.

Example flow: "@alert create incident" in #ops triggers an n8n webhook, which creates a PagerDuty incident and posts confirmation to Mattermost.

Prometheus AlertManager:

Prometheus AlertManager can post alerts to Mattermost using a webhook. In your AlertManager configuration, define a receiver with webhook_configs pointing to your Mattermost incoming webhook URL. When an alert fires, AlertManager POSTs to Mattermost.

Generic Pattern for Any Service:

If a service does not have a Mattermost integration, use a middleman. Services like Zapier, IFTTT, or custom Lambda/Cloud Function can listen on a webhook, transform the data, and POST to Mattermost. The pattern is:

External Service -> Your Transform Layer -> Mattermost Incoming Webhook

This adds a hop but unlocks any integration.

Troubleshooting Common Webhook Issues

Webhook not firing or not posting to channel:

Check the webhook URL is correct. Copy-paste it from Integrations > Incoming Webhooks, not from memory. Verify the channel exists and has the right name. If the webhook specifies channel "#sales" but you create "#Sales", Mattermost will not find it.

Test with cURL from a terminal outside Mattermost to isolate the issue by sending a POST request to your webhook URL with sample JSON data.

Webhook disabled by admin:

If webhook creation is disabled in System Console, you will see an error when creating a webhook. Ask your admin to enable "Incoming Webhooks" in System Console > Integrations > Integration Management.

Payload too large (413 error):

Mattermost has a ~4 MB limit on payloads. If you get a 413 error, reduce your payload size. Remove large attachments, send only summaries, and use links to full data instead of embedding it.

401 Unauthorized (outgoing webhooks):

For outgoing webhooks, your callback endpoint receives an Authorization header with the token. Verify it matches the token Mattermost shows. If tokens do not match, Mattermost regenerated the token or you are using the wrong one.

Callback URL timeout (502/504 error):

If your callback URL is slow to respond, Mattermost times out and retries. Make sure your callback responds in under 30 seconds. If your logic is heavy, move it to a background job and respond immediately.

Post does not trigger outgoing webhook:

Verify the trigger word or channel matches. If you set a trigger word "urgent", but post "URGENT" (uppercase), it may not fire. Check System Console > Integrations > Outgoing Webhooks to see if the webhook is enabled and matches your post.

How Webhooks, Slash Commands, and Bots Work Together

Mattermost has three integration patterns. Webhooks push or pull data. Slash commands are manual: you type /mycommand to trigger an action. Bots are service accounts that post autonomously.

Use webhooks for reactive integration: external services trigger Mattermost messages. Use slash commands for user-driven workflows: a person types a command to query something or start a process. Use bots for continuous behavior: a bot monitors channels and responds to keywords.

Many teams combine all three. A webhook fires an alert, a slash command lets a user check status, and a bot replies with suggestions. See our sibling guide on Mattermost bots for deeper automation patterns.

If you are running Mattermost yourself, webhooks are free. If you use Mattermost Cloud, check your plan: some tiers limit webhook count. Compare self-hosted vs cloud trade-offs on Opsily's Mattermost hosting pages to see which approach fits your scale.

Frequently Asked Questions

What is a Mattermost webhook URL and where do I find it?

A webhook URL is a unique HTTP endpoint Mattermost generates for you. You POST JSON to it to create messages. Find it in Main Menu > Integrations > Incoming Webhooks. Click the webhook name, then copy the URL shown. Keep it private; it grants write access to a channel.

Can I post to a different channel than the one I set when creating the webhook?

Yes. Include channel ID or name in your JSON payload: {"channel": "#sales", "text": "..."} or {"channel": "@username"} for direct messages. The payload channel overrides the webhook default.

What is the difference between incoming and outgoing webhooks?

Incoming webhooks accept external data and post to Mattermost. Outgoing webhooks listen for trigger words or channel events and call external services. Incoming = external to Mattermost. Outgoing = Mattermost to external.

Can I use Mattermost webhooks with Slack tools?

Partially. Many tools send Slack-compatible webhook payloads (Grafana, Datadog, etc.). Mattermost accepts Slack attachment format, so these usually work. But Mattermost does not support all Slack-specific features (e.g., interactive buttons).

How do I secure a webhook URL so it is not exposed?

Store it in an environment variable or secrets manager. Never hardcode it in version control. Use HTTPS only. Rotate the webhook (delete and create a new one) if it leaks. Treat it like an API key.

Can I test a webhook without sending real messages?

Yes. Use cURL to POST test data to your webhook URL with a simple JSON payload. Then check if the message appears in the channel.

What happens if my webhook callback URL is down?

For outgoing webhooks, Mattermost retries a few times then stops. The post still appears in Mattermost; it just does not trigger the external action. For incoming webhooks, you control the endpoint, so if it is down, requests to it fail and messages do not post.

The Bottom Line

Mattermost webhooks are the simplest way to integrate alerts, deployments, and events into your team chat. Incoming webhooks accept external data; outgoing webhooks trigger external actions. Both are easy to set up, but require careful token management and HTTPS security.

Start with incoming webhooks for alerts from Grafana, GitHub, and monitoring tools. Once comfortable, add outgoing webhooks to trigger workflows. If you are managing Mattermost yourself, webhooks are free and scale with your team. Compare self-hosted flexibility and webhook power against managed Mattermost Cloud on Opsily to decide what fits your company size.

Scale Mattermost without DevOps overhead
Opsily runs managed Mattermost with webhooks, bots, and automation built in. Focus on integrations, not infrastructure.
Get Started Free

Ready to self-host your own apps?

One server. Multiple apps. No per-app fees.

Get started →