Developer

HTTP API

Make outbound HTTP requests from custom resources — no backend required.

HTTP API

The HTTP API lets custom resources make outbound HTTP requests directly from the frontend iframe or the optional Node.js backend. This bypasses browser CORS restrictions since requests go through the native Tauri layer.

Capability required: network:http

Standard Requests

Frontend (iframe)

import { createResourceClient } from "@rightplace/sdk";

const rp = createResourceClient();
await rp.ready();

const response = await rp.http.request("https://api.example.com/data", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": "Bearer sk-...",
  },
  body: JSON.stringify({ query: "hello" }),
  timeout: 15000, // ms (default: 30000)
});

console.log(response.status);     // 200
console.log(response.ok);         // true
console.log(response.headers);    // { "content-type": "application/json", ... }
console.log(response.body);       // "{ \"result\": \"world\" }"

Backend (Node.js)

import { createResourceServer } from "@rightplace/sdk/server";

const server = createResourceServer({
  methods: {
    fetchData: async (params, { rp }) => {
      const response = await rp.http.request("https://api.example.com/data", {
        method: "GET",
        headers: { "Authorization": `Bearer ${params.apiKey}` },
      });
      return JSON.parse(response.body);
    },
  },
});

server.start();

Request Options

OptionTypeDefaultDescription
methodstring"GET"HTTP method: GET, POST, PUT, DELETE, PATCH
headersRecord<string, string>{}Request headers
bodystringRequest body (for POST, PUT, PATCH)
timeoutnumber30000Timeout in milliseconds

Response Object

FieldTypeDescription
statusnumberHTTP status code (200, 404, 500, etc.)
statusTextstringStatus reason phrase (“OK”, “Not Found”, etc.)
okbooleantrue if status is 200-299
headersRecord<string, string>Response headers
bodystringResponse body as text

Streaming Requests

For Server-Sent Events (SSE), LLM APIs, or large responses, use the streaming API. Only available from the frontend.

const stream = rp.http.stream("https://api.anthropic.com/v1/messages", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "x-api-key": "sk-...",
    "anthropic-version": "2023-06-01",
  },
  body: JSON.stringify({
    model: "claude-sonnet-4-6",
    max_tokens: 1024,
    stream: true,
    messages: [{ role: "user", content: "Hello" }],
  }),
});

stream.on("data", (chunk) => {
  // Each line of the response as it arrives
  console.log(chunk);
});

stream.on("done", ({ status, headers }) => {
  console.log("Stream complete, status:", status);
});

stream.on("error", (err) => {
  console.error("Stream error:", err);
});

// Cancel the stream
stream.abort();

Stream Events

EventCallbackDescription
data(chunk: string) => voidFired for each line of the response body
done(info: { status, headers }) => voidFired when the stream completes
error(err: string) => voidFired on network or stream error

Stream Methods

MethodDescription
abort()Cancel the stream and stop receiving events

Manifest Configuration

Declare the network:http capability in your resource.json:

{
  "id": "com.example.my-resource",
  "name": "My Resource",
  "version": "1.0.0",
  "apiVersion": 1,
  "capabilities": [
    "network:http"
  ],
  "frontend": {
    "entry": "dist/index.html"
  }
}

Users will see that your resource requests network access when they install it.

Without the SDK

If you’re not using the @rightplace/sdk npm package, you can use the raw postMessage protocol:

// Standard request
window.parent.postMessage({
  type: "rp:request",
  id: "req-1",
  method: "http.request",
  params: {
    url: "https://api.example.com/data",
    method: "GET",
  },
}, "*");

// Listen for response
window.addEventListener("message", (e) => {
  if (e.data.type === "rp:response" && e.data.id === "req-1") {
    console.log(e.data.result); // { status, statusText, ok, headers, body }
  }
});

Examples

Fetch JSON API

const resp = await rp.http.request("https://jsonplaceholder.typicode.com/posts/1");
const post = JSON.parse(resp.body);
console.log(post.title);

POST with Form Data

const resp = await rp.http.request("https://httpbin.org/post", {
  method: "POST",
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
  body: "name=RightPlace&version=1.0",
});

Call an LLM API

const resp = await rp.http.request("https://api.openai.com/v1/chat/completions", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": "Bearer sk-...",
  },
  body: JSON.stringify({
    model: "gpt-4o",
    messages: [{ role: "user", content: "Hello" }],
  }),
});

const data = JSON.parse(resp.body);
console.log(data.choices[0].message.content);