As well as pages, you can define routes with a +server.js file (sometimes referred to as an ‘API route’ or an ‘endpoint’), which gives you full control over the response. Your +server.js file (or +server.ts) exports functions corresponding to HTTP verbs like GETPOSTPATCHPUT and DELETE that take a [RequestEvent](https://kit.svelte.dev/docs/types#public-types-requestevent) argument and return a Response object.

For example we could create an /api/random-number route with a GET handler:

src/routes/api/random-number/+server.ts

import { error } from "@sveltejs/kit"
import type { RequestHandler } from "./$types"
 
export const GET = (({ url }) => {
  const min = Number(url.searchParams.get("min") ?? "0")
  const max = Number(url.searchParams.get("max") ?? "1")
 
  const d = max - min
 
  if (isNaN(d) || d < 0) {
    throw error(400, "min and max must be numbers, and min must be less than max")
  }
 
  const random = min + Math.random() * d
 
  return new Response(String(random))
}) satisfies RequestHandler

The first argument to Response can be a ReadableStream, making it possible to stream large amounts of data or create server-sent events (unless deploying to platforms that buffer responses, like AWS Lambda).

You can use the errorredirect and json methods from @sveltejs/kit for convenience (but you don’t have to).

If an error is thrown (either throw error(...) or an unexpected error), the response will be a JSON representation of the error or a fallback error page — which can be customised via src/error.html — depending on the Accept header. The +error.svelte component will not be rendered in this case. You can read more about error handling here.