Skip to content

hailer.http

Call third-party services through Hailer's server-side proxy instead of calling them directly from the iframe. The request goes to a Hailer API host, which authenticates the current user and forwards the request to the target service.

MethodHost opReturns
fetch(url, options?)http.fetchPromise<HTTPFetchResponse>
upload(url, entries)http.uploadPromise<HTTPFetchResponse>
openWebSocket(url)http.ws.open (streaming)HTTPWebSocket (synchronous)

Authentication

  • The app calls a Hailer API host (e.g. https://api.hailer.com) at the path /proxy/{serviceName}/.... The request is sent with the user's Hailer session cookie.
  • Hailer validates the session, then removes the session cookie before forwarding. The target service does not receive the user's Hailer credentials.
  • Hailer forwards the header x-hailer-user-id with the user's id. The target service identifies the user from this header.

Allowed URLs and registration

Two constraints apply to the URL:

  1. Host allow-list. The URL must start with a Hailer API host — currently https://api.hailer.com, https://api.k8s.hailer.com, or https://api.hailer.local.gd. A URL outside the list is rejected before any request is made.
  2. Registration. The {serviceName} in /proxy/{serviceName}/... must be a service registered in Hailer's backend proxy configuration. Unregistered paths do not route.

Support for third-party targets is being expanded. To register a third-party service for proxying, contact info@hailer.com.

WebSocket URLs are matched against the same host allow-list with wss:///ws:// substituted for https:///http://, and only services registered with WebSocket support accept upgrades.

fetch(url, options?)

ts
const res = await hailer.http.fetch('https://api.hailer.com/proxy/myservice/things', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({ hello: 'world' }),
});
// res: { status, statusText, headers, body }

options (HTTPFetchOptions): method (GET|POST|PUT|DELETE|PATCH, default GET), headers (string→string map), body (string). The response body is text; parse JSON yourself. Response headers come back as a plain object.

upload(url, entries)

postMessage serializes messages as JSON, which does not preserve File/Blob/FormData. File uploads pass base64 field entries; the host reconstructs FormData before forwarding.

ts
const res = await hailer.http.upload(url, [
  { name: 'title', value: 'My upload' },                        // plain field
  { name: 'file', value: base64String, filename: 'photo.png' }, // file field (base64)
]);

Each HTTPUploadEntry is { name, value, filename? }. An entry with filename is decoded from base64 into a file part; one without is appended as a plain form field. Returns the same HTTPFetchResponse shape as fetch.

openWebSocket(url)

Returns an HTTPWebSocket synchronously (not a promise). Hailer opens the proxied socket and streams events to the handlers.

ts
const ws = hailer.http.openWebSocket('wss://api.hailer.com/proxy/myservice/stream');
ws.onopen = () => ws.send('hello');
ws.onmessage = event => console.log(event.data);
ws.onclose = event => console.log(event.code, event.reason);
ws.onerror = () => {};
ws.send('ping');
ws.close(code, reason);

Handlers: onopen, onmessage, onclose, onerror. Methods: send(data: string), close(code?, reason?). Also exposes readyState and connectionId. The socket is torn down when the app is destroyed.

Hailer Developer Documentation