Skip to main content
Incoming webhooks let any service post messages to a MeepaChat channel with a single HTTP request. No OAuth, no bot account — just a URL and a JSON body.

Create a webhook

Via the Developer Portal:
  1. Go to /developer on your MeepaChat instance
  2. Select WebhooksNew Webhook
  3. Choose a server and channel
  4. Copy the webhook URL
Via API:
curl -X POST https://chat.example.com/api/webhooks \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"channel_id": "CHANNEL_ID", "name": "My Webhook"}'
The response includes the webhook token. The full URL is:
https://chat.example.com/api/webhooks/{token}
Treat webhook tokens like passwords. Anyone with the URL can post to that channel.

Post a message

curl -X POST https://chat.example.com/api/webhooks/YOUR_TOKEN \
  -H "Content-Type: application/json" \
  -d '{"content": "Hello from my integration!"}'
A 200 OK response confirms delivery. The message appears in the channel attributed to the webhook name.

Message format

{
  "content": "Plain text message",
  "embeds": [...],
  "thread_key": "optional-grouping-key"
}
All fields are optional, but at least one of content or embeds must be present.

content

Plain text displayed as the message body. Supports the same formatting as regular messages (bold, code blocks, etc.).

thread_key

A string that groups related messages into a thread. Messages with the same thread_key are collapsed under a single thread in the channel. Useful for grouping all notifications from the same PR, issue, or deployment.
{
  "content": "Build failed",
  "thread_key": "build-pr-42"
}

embeds

Rich cards attached to the message. Up to 10 embeds per message.
{
  "embeds": [
    {
      "title": "Pull Request #42 merged",
      "description": "Add support for dark mode",
      "url": "https://github.com/org/repo/pull/42",
      "color": "#6e40c9",
      "author": {
        "name": "alice",
        "icon_url": "https://github.com/alice.png",
        "url": "https://github.com/alice"
      },
      "fields": [
        { "name": "Repository", "value": "org/repo", "inline": true },
        { "name": "Branch", "value": "main", "inline": true }
      ],
      "footer": {
        "text": "GitHub",
        "icon_url": "https://github.com/favicon.ico"
      }
    }
  ]
}

Embed fields

FieldTypeDescription
titlestringBold title text
descriptionstringBody text, supports markdown
urlstringMakes the title a clickable link
colorstringLeft border color as hex, e.g. "#2ea44f"
author.namestringAuthor name shown above title
author.icon_urlstringAuthor avatar URL
author.urlstringAuthor name link
fieldsarrayList of {name, value, inline} key-value rows
footer.textstringFooter text shown below fields
footer.icon_urlstringFooter icon URL
thumbnail.urlstringSmall image shown top-right
image.urlstringLarge image shown below fields
timestampstringISO 8601 timestamp shown in footer

Examples

curl -X POST https://chat.example.com/api/webhooks/TOKEN \
  -H "Content-Type: application/json" \
  -d '{
    "embeds": [{
      "title": "Deployment succeeded",
      "description": "v2.4.1 is live on production",
      "color": "#2ea44f",
      "fields": [
        { "name": "Environment", "value": "production", "inline": true },
        { "name": "Duration", "value": "2m 14s", "inline": true }
      ]
    }]
  }'

Rate limiting

Webhooks are subject to per-token rate limits. Exceeding the limit returns 429 Too Many Requests with a Retry-After header indicating how many seconds to wait. See Rate Limiting for full details.

Security

If you control both ends (e.g., a GitHub webhook posting to MeepaChat via your own relay), verify the incoming signature before forwarding. The Worker template includes HMAC-SHA256 signature verification out of the box.