Docs / Developers / Storage & I/O / Outbound HTTP
BuildSDK 0.10.1

Outbound HTTP

These docs are public. To publish a plugin you need a YourBot account: sign in to open the Dev Portal.

Plugins have --network none in the sandbox — every outbound request goes through the platform proxy. Capability: proxy:http.

resp = ctx.http.get("https://api.example.com/v1/status")
print(resp["status"], resp["body_bytes"])

resp = ctx.http.post(
    "https://api.example.com/webhook",
    body='{"hello": "world"}',
    headers={"Content-Type": "application/json"},
)

# Query-string params - values may be strings or lists (repeated keys)
resp = ctx.http.get("https://api.example.com/search",
    params={"q": "test", "id": ["123", "456"]})

# Custom method
resp = ctx.http.request("PATCH", "https://api.example.com/x/1", body='{"a":1}')

Response shape: {"status": int, "body_bytes": str, "headers": dict, "truncated": bool}. Request bodies are capped at 500 KB, responses at 200 KB (truncated=True if cut), timeout is 8 seconds, and the proxy enforces 30 requests/minute per (server, plugin) — plugins with a legitimate need can be granted a higher per-plugin ceiling after review. Every limit in one place: Limits and quotas.

  • Domain allow-list: only hostnames you declared (manifest or Dev Portal) are reachable. Subdomains are included automatically, so example.com also allows api.example.com.
  • Stripped headers: Authorization, Host, Cookie, Proxy-Authorization, X-Forwarded-* and other smuggling-prone headers are removed. For Bearer-token APIs use secret-backed auth below. For APIs with their own header, a custom header like X-Api-Key passes through. Never put keys in the URL: query strings end up in logs.
  • No redirects, no cookies, no private IPs: redirects are not followed, cookies are never stored, and loopback/private/reserved ranges are rejected.

Authenticated requests (secret-backed auth) v0.8.0

You cannot set Authorization yourself, and you should not hold raw API keys in code. Instead, store the key with ctx.secrets and name it in the call: the platform injects the header server-side and your plugin never sees the value. The secret must be bound to the destination domain (set its allowed domains in the Dev Portal), so a leaked plugin can't replay it elsewhere. Requires storage:secrets.

# Authorization: Bearer <value of MY_API_KEY> is injected by the platform
resp = ctx.http.request("GET", "https://api.example.com/v1/me",
                        secret_auth="MY_API_KEY")

# Non-bearer schemes
resp = ctx.http.request("POST", "https://api.example.com/v1/charge",
                        body='{"amount": 5}',
                        auth={"scheme": "basic", "secret": "MY_API_KEY"})

Note secret_auth and auth live on ctx.http.request(...); the get/post shorthands do not take them. Supported schemes: bearer (what secret_auth= uses), basic and token — putting secrets in query strings is refused.

YourBot docs Reference tables are generated from the code that is running. Ask in Discord Suggest a correction