Chat API
Incoming webhooks and mail
Post into a channel, start a workflow or hand over e-mail with a secret URL instead of an API key.
Base URLhttps://chat.polder.work
These three endpoints are for machines that cannot hold a personal API token: a CI server, a monitoring tool, a mail provider. The secret is part of the URL, there is no Authorization header, and the credential belongs to a channel, workflow or workspace, not to a person.
Warning A URL with a token in the path ends up in access logs. Treat it like a password and roll it if it leaks. Unknown, revoked and switched-off tokens all return the same
404, so a dead token reveals nothing.
Post a message into a channel
/api/webhooks/{token}Posts a message in the channel the webhook belongs to, as the webhook's bot.
Where the URL comes from. Someone who can manage the channel creates an incoming webhook in the channel settings in Chat: a name, the bot name the messages appear under, and optionally a body path. The URL is shown once, when the webhook is created or its token is rolled. Later only a hash is stored.
Payload. JSON. Which part of it becomes the message depends on the webhook:
- Without a body path:
{"text": "…"}. - With a body path (a dotted path such as
issue.titleorcommits.0.message): send whatever your tool already sends. The value at that path becomes the message. Numbers and booleans are turned into text; lists and objects are refused.
The message is trimmed and may be at most 4000 characters. The last payload received is remembered (when it is under 16 KB) so the person setting up the webhook can see what arrived, also when it failed.
curl https://chat.polder.work/api/webhooks/$WEBHOOK_TOKEN \
-H "Content-Type: application/json" \
-d '{"text": "Build 482 passed"}'
{ "id": "01J9Z3K8M2Q4T6V8X0Y2A4C6E8", "channel_id": 12 }
| Status | Meaning |
|---|---|
201 |
Posted. |
404 |
Unknown or revoked token, or the workspace has the Webhooks feature switched off. |
422 |
The channel is archived, or the payload has no usable text: missing text / empty path, value not text, empty, or over 4000 characters. The error names the field (text or body). |
429 |
Rate limit. |
The channel's posting restrictions do not apply to a webhook.
Start a workflow
/api/workflows/{token}Starts the run of a workflow that has the generic webhook trigger. The URL is shown on the workflow in Flows. The JSON body (any object) becomes the variables of the run. This is a lower limit than the message webhook because one workflow can post in several channels.
curl https://chat.polder.work/api/workflows/$WORKFLOW_TOKEN \
-H "Content-Type: application/json" \
-d '{"customer": "Acme", "amount": 120}'
{ "accepted": true, "runId": 904 }
The run is queued; the response does not wait for it. runId is null when nothing was started: the workflow is switched off, or the call came from the workflow's own run. The body is stored on the workflow (replaced by {"_truncated": true} when over 16 KB), even when the workflow is off, so the builder can show what the sender sends.
| Status | Meaning |
|---|---|
202 |
Accepted (also with runId: null). |
404 |
Unknown token, or the workspace has Workflows or Webhooks switched off. |
429 |
Rate limit. |
Receive e-mail
/api/mail/inbound/{token}Where a mail provider posts the e-mails sent to a workspace. Each mail becomes a ticket in the workspace's inbound channel, or a comment when it replies to an existing ticket.
Where the URL comes from. A workspace admin sets this up under the workspace's mail settings in Chat: choose the inbound channel (and optionally the inbound address), and the URL is shown once. Rolling the token invalidates the old URL. Give the URL to your mail provider as its inbound webhook.
Payload. JSON in the provider's own format. The endpoint does not need to be told which provider it is: it reads the sender, recipients, subject, plain-text body (never HTML, quoted replies are stripped), message id and reply headers from the usual field names of Postmark, Lettermint and similar providers (for example FromFull.Email, from, Subject, TextBody, text, MessageID, Headers). A reply is matched to its ticket by a +t<number> tag in the address it was sent to, or else by the message ids it answers.
{ "handled": true }
| Status | Meaning |
|---|---|
200 |
Always, when the token is known. handled is false when the mail was dropped: no sender, inbound channel missing or archived, or tickets switched off for the workspace or channel. The status stays 200 on purpose, so the provider does not retry what will never succeed. |
404 |
Unknown token. |
429 |
Rate limit. |
Note Nothing in the response says which ticket was made. Look in the channel.