Post to a flock
Webhook API reference for AbabilX flocks: endpoint, request formats (JSON, text/plain, multipart with files), every field, and every limit.
Last updated
| Quick reference | |
|---|---|
| Endpoint | POST https://<host>/hooks/chat/<flock-id>/<secret> |
| Auth | The secret in the URL. No header, token or cookie. |
| Body | JSON object, or multipart/form-data when sending files |
| Success | 201 Created, or 200 when event_id repeats |
| CORS | Any origin, no credentials; preflight allowed |
| Rate | 60 messages a minute per flock, 120 requests a minute per IP |
| Machine-readable spec | /openapi/flock-webhook.json (OpenAPI 3.1) |
Quick start
- 1Create a flock and copy its webhook URL (see Flocks).
- 2Save it as the environment variable ABABILX_WEBHOOK_URL.
- 3Send one request:
curl -sS -X POST "$ABABILX_WEBHOOK_URL" \
-H 'Content-Type: application/json' \
-d '{"message":"Deployment of v2.4.1 finished"}'Response, status 201:
{"success":true,"data":{"id":"6f1c2a9e-5b7d-4c1e-9a43-0d2f8b7e1c55","created_at":"2026-10-19T09:30:00.123456Z"}}The URL
Use the URL exactly as the app showed it. Its shape is https://<host>/hooks/chat/<flock-id>/<secret>. The host may be chat.ababilx.com, workspace.ababilx.com or api.ababilx.com: all three reach the same server, so a URL keeps working whichever one it names.
- flock-id is a UUID.
- secret is 64 hex characters. Anyone with it can post, so keep it out of logs, screenshots and public repositories.
- Only POST is served. Any other method, or any other path, answers 404.
Send text (JSON)
The body must be one JSON object. Every field is a string. Unknown fields are ignored.
| Field | Type | Required | Notes |
|---|---|---|---|
| message | string | Yes, unless files are attached | The text. Markdown is rendered: **bold**, _italic_, `code`, code blocks, lists, links, headings. Leading and trailing whitespace is trimmed. |
| content | string | No | Used only when message is empty or missing. |
| event_id | string | No | Up to 200 bytes. The same id within 7 days stores nothing new (see Responses). The X-Webhook-Event-ID header works too; the body wins if both are set. |
{
"message": "**Build failed** on `main`\n\n- job: test\n- commit: a1b0fbe\n\n[Open the run](https://ci.example.com/runs/812)",
"event_id": "ci-run-812"
}Slack-style bodies do not work as they are. A body with only a text field ({"text":"…"}) has no message, so it answers 400 content or file is required. Rename text to message.
Request examples
{"message": "Deployment finished"}{
"message": "Order #1042 paid: 2,450 BDT",
"event_id": "order-1042-paid"
}{
"message": "## Build failed\n\n**Branch:** `main`\n**Commit:** a1b0fbe\n\n- test: 3 failed\n- lint: ok\n\n[Open the run](https://ci.example.com/runs/812)"
}{
"message": "Error in checkout:\n\n```\nTypeError: cannot read 'total' of undefined\n at pay (cart.js:41)\n```"
}{"content": "Disk on db-1 is 91% full"}{}curl -sS -X POST "$ABABILX_WEBHOOK_URL" \
-H 'Content-Type: application/json' \
-H 'X-Webhook-Event-ID: backup-2026-10-19' \
-d '{"message":"Backup finished"}'{"text": "hi"} → 400 content or file is required (use "message")
{"message": 42} → 400 invalid request body (must be a string)
["hello"] → 400 invalid request body (must be an object)
message=hello (form post) → 400 invalid request body (send JSON)Content-Type
| Content-Type sent | How the body is read |
|---|---|
| application/json | JSON object. The normal choice. |
| text/plain (or none) | Also read as JSON. Useful in a browser: a text/plain POST needs no CORS preflight. |
| multipart/form-data | payload_json field holds the JSON; files[n] fields hold files. |
| application/x-www-form-urlencoded | Not supported: the body is read as JSON and fails with 400 invalid request body. |
Send files (multipart)
Send multipart/form-data. Put the JSON body, as text, in a field named payload_json (exactly one). Put each file in its own field named files[0], files[1] … files[9]. A message may be files only: send payload_json as {}.
curl -sS -X POST "$ABABILX_WEBHOOK_URL" \
-F 'payload_json={"message":"Nightly report","event_id":"report-2026-10-19"}' \
-F 'files[0]=@report.pdf' \
-F 'files[1]=@chart.png;type=image/png'- Up to 10 files per message, 350 MB in total, and no empty files.
- Any file type. Send the right Content-Type on each part so pictures and videos are shown inline; unknown types arrive as downloadable files.
- File names: up to 255 bytes; any folder part of the name is dropped.
- Files show in the order of their field names, so use files[0] to files[9].
- Fields not named payload_json or files[n] are ignored.
All limits
| What | Limit | Over the limit |
|---|---|---|
| Text length | 6,000 bytes of UTF-8 (about 6,000 English letters or 2,000 Bangla letters) | 400 content exceeds 6000 characters |
| Words | 1,000 | 400 content exceeds 1000 words |
| JSON body | 64 KB | 400 invalid request body |
| Multipart body | 351 MB | 400 invalid request body |
| Files per message | 10 | 400 max 10 attachments allowed |
| File size | 1 byte to 350 MB each, 350 MB together | 400 invalid file size / attachments exceed 350 MB total limit |
| event_id | 200 bytes | 400 event_id too long |
| Messages per flock | 60 in any 60 seconds | 429 rate_limit_exceeded |
| Requests per IP to flock URLs | 120 in any 60 seconds (wrong URLs count too) | 429 rate_limit_exceeded |
| Requests per IP to the whole API | 100 at once, then 50 a second | 429 too many requests, slow down |