PowerKeys Scripting API
    Preparing search index...

    Interface HTTPAPI

    interface HTTPAPI {
        SendRequest(options: HttpRequestOptions): Promise<HttpResponse>;
        RequestJson<T = unknown>(
            options: HttpRequestOptions,
        ): Promise<HttpJsonResponse<T>>;
        UploadFile(options: HttpUploadFileOptions): Promise<HttpUploadFileResponse>;
        DownloadFile(
            options: HttpDownloadFileOptions,
        ): Promise<HttpDownloadFileResponse>;
    }
    Index
    • Sends one HTTP request to an allowed host and resolves with every real HTTP response, including 3xx, 4xx, and 5xx statuses.

      Parameters

      Returns Promise<HttpResponse>

      A promise for the real HTTP status, lowercase duplicate-preserving response headers, and bounded response body.

      Redirects and retries are disabled. Response-header names are lowercase; each value array preserves duplicate field occurrences in receive order for that name. Response bodies are decoded as UTF-8 with malformed bytes replaced and use one-eighth of the effective script heap as an availability and memory budget, not an exfiltration-security boundary. The default timeout is 30000 ms, the allowed range is 100-120000 ms, and at most four requests may be in flight per script. URLs are limited to 8 KiB; request bodies and headers have no PowerKeys size or count cap, though the bundled HTTP/1 parser accepts at most 100 response header fields. The connection attempt itself is bounded at 10 seconds regardless of timeoutMs. Client-owned framing headers are rejected, specifically connection, content-length, host, keep-alive, proxy-authorization, proxy-connection, te, trailer, transfer-encoding, and upgrade, as are two header names that differ only by case. Rejected calls are Error objects with a stable HttpSendRequestErrorCode in error.code. A call refused for concurrency rejects with the retryable busy code rather than invalid_request, and a response over the body budget rejects with limit_exceeded rather than network. System-level script stop remains an informational lifecycle cancellation.

      const response = await HTTP.SendRequest({
      url: "https://api.example.com/items",
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ name: "test" }),
      timeoutMs: 5000,
      });
      Console.Log(`${response.statusCode}: ${response.body}`);

      network

    • Sends an HTTP request and parses the non-empty response body.

      Type Parameters

      • T = unknown

      Parameters

      Returns Promise<HttpJsonResponse<T>>

      The real status and headers plus the value parsed from the response body. See the data field for what an empty body resolves to.

      Every real HTTP response resolves after parsing, including non-2xx statuses. Content-Type is not consulted: empty or whitespace-only bodies return data: null, and every other body must parse as JSON; a non-empty invalid body rejects with HttpJsonParseError without including body contents in its message. Transport, timeout, permission, and cancellation failures pass through unchanged from HTTP.SendRequest. T is a compile-time assertion only, not runtime schema validation.

      const response = await HTTP.RequestJson<{ items: Array<{ title: string }> }>({
      url: "https://api.example.com/feed",
      });
      if (response.statusCode === 200 && response.data !== null) {
      Console.Log(response.data.items[0]?.title ?? "No items");
      }

      network

    • Streams one local file to an allowed HTTP host.

      Parameters

      Returns Promise<HttpUploadFileResponse>

      The real HTTP status, bounded response body, and streamed byte count.

      The source is a relative path inside this script's native-owned workspace: absolute paths, drive or UNC prefixes, and any path leaving the workspace are rejected, as is a path over 512 bytes or 16 components. Links and reparse points are never followed, and the source must be a regular file that already exists. The transfer uses fixed 64 KiB native chunks and never exposes file bytes to JavaScript, so file size is limited by disk rather than by the script heap. maxBytes is caller-owned protection, not a PowerKeys file-size cap; exceeding it rejects with limit_exceeded. There is deliberately no total timeout, because a large upload legitimately takes minutes; a peer that stops accepting bytes for 60 seconds rejects with timeout. One transfer runs at a time per script and a second concurrent call rejects with the retryable busy code. The response body is subject to the same heap-derived budget as HTTP.SendRequest. Rejections are Error objects carrying a stable HttpSendRequestErrorCode.

      await Workspace.WriteText("out/report.csv", "name,count\nalpha,3\n");
      const uploaded = await HTTP.UploadFile({
      url: "https://api.example.com/import",
      path: "out/report.csv",
      method: "PUT",
      });
      Console.Log(`${uploaded.statusCode}: sent ${uploaded.bytesTransferred} bytes`);

      network

      workspace

    • Streams an HTTP response into a local file.

      Parameters

      Returns Promise<HttpDownloadFileResponse>

      The real status and headers; a non-2xx response writes no file and reports zero transferred bytes. See the path field for what it resolves to then.

      The destination is a relative path inside this script's native-owned workspace, under the same rules as HTTP.UploadFile: no absolute, drive, UNC, or escaping paths, at most 512 bytes and 16 components, and no link or reparse point anywhere along it. Missing intermediate directories are created. Only 2xx responses write a file; every other status resolves with its real status, a null path, and zero bytes. Downloads use a same-volume temporary file and an atomic no-clobber commit, so an existing destination is never replaced and is left untouched on cancellation or failure; use Workspace.Delete or Workspace.Move first when replacing is intended. maxBytes is an optional caller control with no PowerKeys file-size cap, checked against Content-Length before reading and against the streamed bytes while reading, and exceeding it rejects with limit_exceeded. There is deliberately no total timeout, because a large download legitimately takes minutes; a peer that sends no chunk for 60 seconds rejects with timeout. One transfer runs at a time per script and a second concurrent call rejects with the retryable busy code.

      const downloaded = await HTTP.DownloadFile({
      url: "https://cdn.example.com/data.csv",
      path: "in/data.csv",
      maxBytes: 50_000_000,
      });
      if (downloaded.path !== null) {
      Console.Log(await Workspace.ReadText("in/data.csv"));
      }

      network

      workspace