Home / Integrations

Outbound network API

This is a Lua API for plugin code—not a console command or a manually sent request. A plugin calls the function; the server sends it in the background and invokes the callback on a later game tick.

Use asynchronous HTTPS, TCP, and UDP exchanges for Discord webhooks, Telegram bots, or your own bot service.

Enable destinations

plugin-net-allowlist is optional. If it is empty (the default), the helper API accepts any publicly routable host or IP; no API key or subscription is required. If you fill it, only the exact listed hosts or host-and-port pairs are accepted.

plugin-net-allowlist=discord.com,api.telegram.org,bot.example.net:9000,bot.example.net:9001

A bare host permits HTTPS on port 443. TCP/UDP require an exact host:port entry. IPv4 addresses work like hostnames; put IPv6 endpoints in brackets, e.g. [2001:db8::20]:9000. Wildcards are not supported. Local/private, link-local, and multicast addresses remain blocked by these helpers.

Optional server controls:

plugin-net-denylist=blocked.example.net,203.0.113.10:443
plugin-net-requests-per-minute=300

The denylist blocks exact host or address entries; an entry without a port blocks every port for that host/address. The per-plugin request limit defaults to 300 submissions per minute and may be set from 1 to 3000. Invalid or non-positive values use the default.

HTTPS

net.https.request(options, callback)
net.https.request({
  method = "POST",
  url = "https://discord.com/api/webhooks/...",
  headers = { ["Content-Type"] = "application/json" },
  body = '{"content":"Server is online"}',
  timeoutMs = 5000
}, function(response)
  if not response.ok then
    log("Webhook failed", response.status or response.error)
  end
end)

Use a complete HTTPS URL because the path identifies the service action. The URL host can be a domain or public IP; for example, https://203.0.113.10/hook (the certificate must be valid for that IP). Supported methods: GET, POST, PUT, and DELETE. Redirects are disabled. A response contains ok, status, and body (also available as data), plus error when applicable.

HTTPS resolves the URL host once, rejects the request if any resolved address is local/private, link-local, or multicast, and connects to a validated address. TLS SNI and certificate verification still use the URL hostname. The helper uses a direct connection rather than a configured proxy.

For Telegram, allowlist api.telegram.org and send a JSON POST to its /bot<TOKEN>/sendMessage endpoint. Keep bot tokens in a private config file rather than committing or logging them.

TCP and UDP

net.tcp.send(host, port, payload, callback) net.udp.send(host, port, payload, callback)
net.tcp.send("bot.example.net", 9000, "status\n", function(result)
  if result.ok then
    log("Bot replied:", result.data)
  else
    log("TCP request failed:", result.error)
  end
end)

Pass a domain or IP directly as host and the port separately; no URL is needed for sockets. These are one-shot outbound exchanges, not listeners. TCP sends the payload, closes its output side, then reads a response. UDP sends one datagram and waits for one reply. Both return ok, data, and, on failure, error.

For an IP-based service, the host argument is just the address, e.g. "203.0.113.10" (replace this documentation-only example with your service's public IP). For HTTPS, put the IP in the URL; the remote TLS certificate must include that IP.

Limits and trust

This API is not a plugin sandbox. LuaJ Java interop and file access are still available, so a trusted plugin can use Java directly and bypass these helper limits. Only install code you have reviewed and trust.