Skip to content

API Routes

API routes let you build JSON endpoints alongside your pages.

Create a +server.ts file and export named HTTP verb functions:

src/routes/api/hello/+server.ts
import type { RequestEvent } from "bosia";
export function GET({ params, locals }: RequestEvent) {
return Response.json({
message: "Hello from Bosia API!",
user: locals.user,
});
}
export async function POST({ request }: RequestEvent) {
const body = await request.json().catch(() => ({}));
return Response.json({ received: body });
}

Supported exports: GET, POST, PUT, PATCH, DELETE, OPTIONS.

Every handler receives a RequestEvent:

PropertyTypeDescription
requestRequestThe raw Web API Request object
urlURLParsed request URL
paramsRecord<string, string>Dynamic route parameters
localsRecord<string, any>Data set by middleware hooks
cookiesCookiesRead/write cookies

Return standard Web API Response objects:

// JSON
return Response.json({ ok: true });
// Custom status
return Response.json({ error: "Not found" }, { status: 404 });
// Plain text
return new Response("Hello", { status: 200 });
// Custom headers
return new Response(null, {
status: 204,
headers: { "X-Custom": "value" },
});

Use dynamic segments just like pages:

src/routes/api/users/[id]/+server.ts → /api/users/123
export function GET({ params }: RequestEvent) {
return Response.json({ userId: params.id });
}
export function DELETE({ params }: RequestEvent) {
return Response.json({ deleted: params.id });
}

If a request hits a +server.ts that doesn’t export the requested method, Bosia responds with 405 Method Not Allowed and an Allow header listing the supported methods.

Data set in hooks.server.ts is available in every API handler:

export function GET({ locals }: RequestEvent) {
if (!locals.user) {
return Response.json({ error: "Unauthorized" }, { status: 401 });
}
return Response.json({ user: locals.user });
}