Wiki 9Minecraft Wiki 9Minecraft

Script Requests API (@minecraft/server-net)

How to send outbound HTTP requests from a Bedrock Dedicated Server using the @minecraft/server-net module.

5Sections
2Code examples
3Known errors

The Script Requests API, provided by the @minecraft/server-net module, lets a behavior pack script make outbound HTTP requests to external web services. You reach for it when a Bedrock Dedicated Server needs to talk to an external database, post match results to a webhook, or pull live configuration data from a backend you control. This module does not exist in singleplayer worlds, Realms, or local LAN sessions; it is strictly a Dedicated Server feature.

When and Where It Works

Standard Minecraft Bedrock worlds run in a tight sandbox with no external network access from scripts. This protects players who download add-ons from having their IP addresses or session data leaked to third-party servers. Because of this security boundary, the @minecraft/server-net module is completely excluded from the standard game client and from Realms.

To use this API, your behavior pack must be loaded onto a Bedrock Dedicated Server (BDS), and the server operator must explicitly grant permission for the module to run and whitelist the specific URIs or domains your script wants to contact. If you are building a marketplace pack or an add-on meant for normal players to import on mobile, console, or Windows client, you cannot use this API.

Manifest and Server Configuration

Like any other script module, you must declare @minecraft/server-net in the dependencies array of your behavior pack's manifest.json. As of recent Bedrock releases, the networking module remains in the beta track, meaning the version string requires the -beta suffix and the world itself must have the Beta APIs experimental toggle enabled.

Declaring the dependency in the manifest is only half the setup. On the Bedrock Dedicated Server host machine, the administrator must configure the permissions file inside the server's config directory (specifically the default/permissions.json file used for script module authorization) to enable @minecraft/server-net and list the allowed destination URIs. Without server-side authorization, the game will refuse to load the script module even if the manifest is valid.

BP/manifest.json
{
  "format_version": 2,
  "header": {
    "name": "Server Telemetry Pack",
    "description": "Sends server events to a local web backend.",
    "uuid": "a1b2c3d4-e5f6-4a5b-8c9d-0e1f2a3b4c5d",
    "version": [1, 0, 0],
    "min_engine_version": [1, 20, 80]
  },
  "modules": [
    {
      "type": "script",
      "language": "javascript",
      "uuid": "f1e2d3c4-b5a6-4f5e-8d9c-0b1a2f3e4d5c",
      "entry": "scripts/main.js",
      "version": [1, 0, 0]
    }
  ],
  "dependencies": [
    {
      "module_name": "@minecraft/server",
      "version": "1.11.0"
    },
    {
      "module_name": "@minecraft/server-net",
      "version": "1.0.0-beta"
    }
  ]
}

Core Classes and Enums

The @minecraft/server-net module is small and revolves around a single singleton object named http, along with classes for building requests and reading responses. Unlike the browser Fetch API which might already be familiar to JavaScript developers, Bedrock uses its own HttpRequest class to configure headers, body text, and timeouts before passing the object to http.request().

All network calls are asynchronous and return a standard JavaScript Promise that resolves to an HttpResponse object. Because the server ticks independently while waiting for the network reply, you should always handle the resolved data carefully—players may have disconnected or entities may have despawned by the time a slow web server responds.

ExportWhat it doesNotes
httpMain entry point for executing requestsProvides http.get(uri), http.request(config), and http.cancelAll(reason).
HttpRequestConstructs a customized outbound requestHolds the URI, method, headers, body, and timeout before sending.
HttpHeaderRepresents a single key-value HTTP headerSecrets can be passed using a SecretString from @minecraft/server-admin.
HttpRequestMethodEnum of supported HTTP verbsIncludes Get, Post, Put, Delete, and Head.
HttpResponseObject returned when the request Promise resolvesContains status (number), body (string), and headers (HttpHeader[]).

Making GET and POST Requests

For a quick read operation where you do not need custom headers or a request body, http.get() is the shortest path. You pass the target URI string, await the Promise, and read the status and body properties off the returned HttpResponse.

When sending data—such as logging a player chat event or updating an external leaderboard via JSON—you instantiate an HttpRequest, set its method to HttpRequestMethod.Post, attach an application/json Content-Type header, and serialize your payload with JSON.stringify(). It is also good practice to call setTimeout() (measured in seconds) so a dead backend does not leave promises hanging indefinitely.

BP/scripts/main.js
import { world, system } from "@minecraft/server";
import { http, HttpRequest, HttpHeader, HttpRequestMethod } from "@minecraft/server-net";

// Simple GET request to check backend health on world load
system.runTimeout(async () => {
  try {
    const response = await http.get("http://127.0.0.1:8080/status");
    if (response.status === 200) {
      console.warn("Backend connected: " + response.body);
    } else {
      console.warn("Backend returned status: " + response.status);
    }
  } catch (err) {
    console.error("GET request failed: " + err);
  }
}, 20);

// POST request sending JSON data when a player joins
world.afterEvents.playerSpawn.subscribe(async (event) => {
  if (!event.initialSpawn) return;

  const req = new HttpRequest("http://127.0.0.1:8080/api/player-join");
  req.setMethod(HttpRequestMethod.Post);
  req.setTimeout(5);
  req.setHeaders([
    new HttpHeader("Content-Type", "application/json"),
    new HttpHeader("Accept", "application/json")
  ]);

  const payload = {
    playerName: event.player.name,
    playerId: event.player.id,
    timestamp: Date.now()
  };
  req.setBody(JSON.stringify(payload));

  try {
    const response = await http.request(req);
    if (response.status === 200) {
      const data = JSON.parse(response.body);
      if (data.welcomeMessage) {
        event.player.sendMessage(data.welcomeMessage);
      }
    }
  } catch (err) {
    console.error("Failed to notify backend of player join: " + err);
  }
});

Handling Secrets and Cancellations

Hardcoding API keys or bearer tokens directly inside your behavior pack scripts is risky because anyone with access to the pack files can read your plain-text JavaScript. Instead, pair @minecraft/server-net with the @minecraft/server-admin module. The server-admin module provides a secrets object that reads sensitive strings from the server's configuration directory and returns a SecretString instance. You can pass that SecretString directly into the value parameter of new HttpHeader(), and the engine will inject the real token into the outbound packet without ever exposing the raw string to the script environment.

If your script queues up many slow requests and you need to flush them—for instance, during a custom minigame reset—you can call http.cancelAll("Reason for cancellation"). Every pending Promise created by http.get() or http.request() will immediately reject with the reason string you provided, so make sure all awaited network calls are wrapped in try/catch blocks.

Which versions this applies to

Applies to Bedrock Dedicated Server 1.19.40 and newer. Because @minecraft/server-net is currently versioned as 1.0.0-beta, the world must have the Beta APIs experimental toggle enabled, and the pack can only be run on a properly configured Dedicated Server.

When it does not work

What you seeWhyThe fix
Content Log shows: Module [@minecraft/server-net] does not exist or cannot be resolved when loading the world.You are either trying to load the pack in a standard Minecraft client / Realm where the module is stripped out, or you are on a Dedicated Server that has not enabled @minecraft/server-net in its config/default/permissions.json file.Run the pack exclusively on a Bedrock Dedicated Server and add "@minecraft/server-net" to the allowed modules list inside the server's permissions configuration.
The Promise returned by http.request() rejects immediately with a permission or URI error.Even when the module is enabled on the Dedicated Server, outbound requests are blocked by default unless the destination URI matches the server's allowlist, or the Beta APIs toggle is missing.Add the target domain or local IP address to the allowed URIs list in the server configuration, and verify that the world's level.dat has the Beta APIs experiment turned on.
Remote API returns HTTP 400 or 415 and ignores the body sent by setBody().HttpRequest does not automatically infer content types when you pass a JSON string to setBody().Explicitly attach new HttpHeader("Content-Type", "application/json") using req.setHeaders() or req.addHeader() before calling http.request(req).

Reference, straight from the game files

Read out of the game itself, so the ids match the version you are building for.