Skip to content

HTTP API

HttpApi lets you describe an HTTP API once, as a tree of typed endpoints, and then derive everything else from that single definition:

  • a server that validates requests and encodes responses against your schemas,
  • a typed client whose method signatures mirror your endpoints exactly, and
  • OpenAPI documentation (Scalar or Swagger UI) generated from the same source.

Because the definition is built from Schema, every payload, path parameter, query value, response and error is decoded and encoded at runtime and checked end-to-end at compile time. Rename an endpoint or change a field and both the server handlers and the client call sites stop compiling until you fix them.

An API is composed of endpoints, grouped into groups, combined into a single HttpApi:

import { Schema } from "effect"
import { HttpApi, HttpApiEndpoint, HttpApiGroup } from "effect/unstable/httpapi"
// A group bundles related endpoints under a common path prefix
class UsersGroup extends HttpApiGroup.make("users")
.add(
// GET /users/:id -> 200 with a decoded `name`
HttpApiEndpoint.get("getById", "/:id", {
params: { id: Schema.FiniteFromString },
success: Schema.Struct({ id: Schema.Number, name: Schema.String })
})
)
.prefix("/users")
{}
// The root API combines all groups. This value is shared by server and client.
class Api extends HttpApi.make("acme-api").add(UsersGroup) {}

The Api value is the contract. The server implements it, the client consumes it, and the OpenAPI generator documents it — all from this one declaration.

Defining APIs

Describe groups, endpoints, path params, queries, payloads, responses and errors. Read more

Middleware & auth

Secure endpoints, inject the current user, and define security schemes. Read more

Serving & clients

Serve the API and call it with a generated, fully typed client. Read more

OpenAPI

Generate an OpenAPI spec and interactive docs from the definition. Read more

The pages that follow build up the same example API incrementally. If you want the lower-level request/response building blocks instead, see the HTTP Client section and the Platform HTTP server primitives.