Kumo Studio

Settings

Cloudflare credentials for one-click DNS, and the webhook KumoMTA reports bounces to.

Cloudflare

Used by the "Add to Cloudflare" button on the Domains page. Create a token with Zone → DNS → Edit permission for the zones you send from.

KumoMTA bounce webhook

Point a KumoMTA log/webhook hook at this address to record hard and soft bounces. Prefix it with this studio's own public URL (the address you use to reach it in a browser) — it's shown here as a path only since the app can't see its own public hostname. It expects a JSON body:

{
  "type": "bounce" | "transient_failure" | "delivery",
  "id": "<the X-PStudio-Mid header value from the message>",
  "recipient": "[email protected]",
  "code": 550,
  "message": "free text"
}
Webhook path — append to your app's URL
/hooks/kumomta?key=5c2dd1de33b9429cb13e00581859c700dac823a289fe44e096895d7cadeebcd6
Example KumoMTA policy snippet (init.lua)
-- Replace https://your-app-url with this studio's actual public address.
kumo.on('log_record', function(msg)
  local rt = msg.type
  if rt == 'Bounce' or rt == 'OOB' or rt == 'TransientFailure' then
    local kind = (rt == 'TransientFailure') and 'transient_failure' or 'bounce'
    kumo.spawn_task(function()
      kumo.http.request('POST', 'https://your-app-url/hooks/kumomta?key=5c2dd1de33b9429cb13e00581859c700dac823a289fe44e096895d7cadeebcd6')
        :header('Content-Type', 'application/json')
        :body(kumo.serde.json_encode({
          type = kind,
          id = msg.headers['X-PStudio-Mid'],
          recipient = msg.recipient,
          code = msg.response and msg.response.code,
          message = msg.response and msg.response.content,
        }))
        :send()
    end)
  end
end)