Skip to content

Web endpoints

A Function with web serves its fetch handler at a *.modal.run URL. Modal starts containers as requests arrive, like it does for calls.

A web endpoint answers anyone unless it requires proxy auth. Then Modal’s proxy checks each request’s token before it reaches a container:

Modal-Key · Modal-Secret401acme--site.modal.runrequiresProxyAuthanyoneno tokenApiWorker · FetchServerSiteFunction · webModal-Key · Modal-Secret401acme--site.modal.runrequiresProxyAuthanyoneno tokenApiWorker · FetchServerSiteFunction · web
With requiresProxyAuth, a request reaches Site only with a webhook token's Modal-Key and Modal-Secret headers. FetchServer adds them for the Worker.
src/Site.ts
import * as Modal from "@alchemy.run/modal";
import * as Effect from "effect/Effect";
import * as HttpServerResponse from "effect/http/HttpServerResponse";
import { Inference } from "./Inference.ts";
export default class Site extends Modal.Function<Site>()(
"Site",
{ main: import.meta.url, app: Inference, web: true },
Effect.gen(function* () {
return { fetch: Effect.succeed(HttpServerResponse.text("hello from Modal")) };
}),
) {}

The URL is the url attribute.

{ main: import.meta.url, app: Inference, web: { label: "site" } }

The URL becomes https://<workspace>--site.modal.run.

{ main: import.meta.url, app: Inference, web: { requiresProxyAuth: true } }

Callers then send the Modal-Key and Modal-Secret headers of a Modal.WebhookToken.

const site = yield* Modal.FetchServer(Site);
const response = yield* site.fetch(HttpClientRequest.get("/"));

FetchServer adds the proxy auth headers for you.