API

When you create a new Faire Auth instance, it provides you with an api object. This object exposes every endpoint that exists in your Faire Auth instance, keyed by operationId. You can use this to interact with Faire Auth server-side.

Any endpoint added to Faire Auth, whether from plugins or the core, will be accessible through the api object.

Calling API Endpoints on the Server

To call an API endpoint on the server, import your auth instance and call the endpoint using the api object.

server.ts
import { faireAuth, defineOptions } from "faire-auth";
import { headers } from "next/headers";

const cfg = defineOptions({
    baseURL: "http://localhost:3000",
})

const auth = faireAuth(cfg)

// calling get session on the server
await auth.api.getSession(
    { query: {} },
    { headers: await headers() },
)

Input and Options

Server API calls take two arguments: the input (json, query, param) and options (headers, asResponse, returnHeaders).

server.ts
await auth.api.getSession(
    { query: {} },
    { headers: await headers() },
)

await auth.api.signInEmail(
    { json: { email: "john@doe.com", password: "password" } },
    { headers: await headers() }, // optional but useful for IP, user agent
)

await auth.api.verifyEmail({
    query: { token: "my_token" },
})

Faire Auth's API layer is built on Hono using OpenAPIHono, which provides type-safe endpoints with automatic OpenAPI schema generation. This lets you call REST API endpoints as if they were regular functions and allows us to infer client types from the server.

Type Inference with $Infer

Faire Auth provides powerful type inference through the $Infer namespace:

server.ts
import { faireAuth, defineOptions } from "faire-auth";

const cfg = defineOptions({
    baseURL: "http://localhost:3000",
    plugins: [organization(), twoFactor()],
})

const { $Infer } = faireAuth(cfg)

// Get the full typed Hono app — use this to type your client
export const App = $Infer.App(cfg)

// Get the typed server-side API object
export const Api = $Infer.Api(App)

// Get the session type (user + session with plugin fields)
type Session = typeof $Infer.Session

Getting headers and Response Object

When you invoke an API endpoint on the server, it will return a standard JavaScript object or array directly as it's just a regular function call.

But there are times when you might want to get the headers or the Response object instead. For example, if you need to get the cookies or the headers.

Getting headers

To get the headers, you can pass the returnHeaders option to the endpoint.

const { headers, response } = await auth.api.signUpEmail(
	{
		json: {
			email: "john@doe.com",
			password: "password",
			name: "John Doe",
		},
	},
	{ returnHeaders: true },
);

The headers will be a Headers object, which you can use to get the cookies or the headers.

const cookies = headers.get("set-cookie");
const customHeader = headers.get("x-custom-header");

Getting Response Object

To get the Response object, you can pass the asResponse option to the endpoint.

server.ts
const response = await auth.api.signInEmail(
    { json: { email: "", password: "" } },
    { asResponse: true },
)

Error Handling

Server API calls do not throw on HTTP error status codes. Instead, they return an object with success: false and a message:

server.ts
const res = await auth.api.signInEmail({
    json: {
        email: "wrong@email.com",
        password: "wrong"
    }
})

if (res.success === false) {
    console.log(res.message) // "Invalid email or password"
}

On the client, errors are returned in the error field:

client.ts
const { data, error } = await client.signIn.email.$post({
    json: { email, password },
})

if (error) {
    console.log(error.message, error.status) // "Invalid email or password", 401
}

Edge Deployment

The handler returned by faireAuth() supports edge runtimes natively. It accepts optional Cloudflare Worker bindings and execution context:

worker.ts
const auth = faireAuth(cfg)

export default {
    fetch(request: Request, env: Env, ctx: ExecutionContext) {
        return auth.handler(request, env, ctx)
    }
}

On this page