Skip to content
noel.marketing

Astro

Astro endpoints without a separate backend

Noel

Written by Noel
Published:
19 min read

Topics researched with AI assistance; reviewed and edited by Noel before publishing.

Developer reviewing Astro endpoint files in a code editor

Explore this topic

More Astro guides, glossary entries, and practical workflows live on the topic hub.

Astro endpoints let you create custom responses from the same project that renders your pages. In other words, you can use Astro to serve JSON, RSS, images, and API-style responses without standing up a separate backend for every small task.

For merchants and developers, that matters because a storefront or content site often needs more than HTML. Product feeds, sitemap-like outputs, downloadable data, and request-time lookups all fit naturally into one codebase when you understand how astro endpoints api routes behave in static and SSR modes.

Key takeaways

  • Astro endpoints can produce static files at build time or live responses at request time.
  • The same route file pattern can support JSON, images, feeds, and other non-page outputs.
  • Static mode is best when the output can be precomputed; SSR is better when the response depends on the request.
  • Dynamic routes work for endpoints too, but static generation needs getStaticPaths().
  • The main risk is treating endpoints like a full backend when a smaller, simpler response is enough.

What is it?

Astro endpoints are route files that return a Response instead of a page component. They let you define custom outputs under your site’s routing system, so a file can build into /data.json, /feed.xml, or another non-HTML resource. In static projects, Astro runs the endpoint during build and writes the result to disk. In SSR projects, the same route can run on demand when a request arrives.

A practical example is a JSON feed for recent blog posts. Instead of building that feed in a separate service, you can place an endpoint in your Astro project and have it return the data directly. The route can be read by browsers, feed readers, or other systems that expect a structured response.

The key idea is that the endpoint is not limited to one content type. The response can be text, JSON, XML, or binary data, as long as the route returns the right Response object. That makes endpoints useful anywhere a site needs a machine-readable output alongside its normal pages.

For merchants, this is often the simplest way to expose content that another tool needs to consume. For developers, it keeps routing, data access, and output generation in one place, which reduces the number of moving parts you have to maintain.

Astro’s endpoint model is also broader than the phrase “API route” suggests. A route can behave like a classic API endpoint, but it can also generate a file that is later served as a static asset. That dual purpose is what makes the feature especially useful in content-heavy sites: one implementation pattern covers both build-time exports and runtime responses.

If you are coming from another framework, the easiest mental model is this: a page route is for rendering UI, while an endpoint route is for returning a payload. The payload might be consumed by a browser, a feed reader, a script, or another service. In a small team, that distinction can simplify architecture decisions because you do not need to invent a separate service just to ship a structured document.

Static file endpoints vs live API routes

The most useful distinction is not “endpoint or not,” but “static or live.” A static endpoint is ideal when the output is derived from content that already exists in your repository or CMS and does not need to change until the next deploy. A live API route is better when the response depends on the current request, current inventory, authentication state, or another runtime-only factor.

That difference affects more than performance. It changes how you test, cache, and deploy the route. A static endpoint is easy to preview because its output is deterministic. A live route needs request-level checks, but it can also return fresh data and status codes that reflect the current state of the system. Choosing the wrong mode usually creates avoidable complexity: a static route that should have been live becomes stale, while a live route that should have been static becomes harder to cache and maintain.

Why it matters

The business value of Astro endpoints is mostly about reducing friction. If a site already runs on Astro, an endpoint can replace a small external service, a manual export, or a brittle script. That means fewer systems to deploy, fewer credentials to manage, and fewer places where content can drift out of sync.

From a technical standpoint, endpoints give you a clean way to separate presentation from delivery. A page component is for humans; an endpoint is for machines or specialized outputs. That distinction helps teams avoid stuffing data-export logic into page templates or custom client-side code that is harder to maintain.

This matters especially when content changes often. If a catalog, feed, or structured data file needs to stay current, build-time generation can be enough for many projects. If the response needs to reflect the latest request, user input, or server-side checks, SSR endpoints give you that flexibility without changing your whole stack.

There is also a performance angle. Static endpoints can be fast because they are just files served by the host. SSR endpoints still keep the logic close to the site, but they only run when needed. In both cases, you can avoid unnecessary client-side work and keep the browser focused on rendering the page itself.

A less obvious benefit is operational clarity. When the route lives in the same repository as the content and templates, it is easier to review changes together. If a feed format changes, the content source and the endpoint logic can be updated in the same pull request. That reduces the chance that a deployment ships pages that do not match the data export or that an external integration keeps reading an outdated format.

For teams with limited engineering time, that simplicity is valuable. You can support a practical amount of API-like behavior without introducing a separate backend stack, a separate release process, or a separate monitoring surface. The result is not just less code; it is less coordination overhead.

How it works

Astro endpoints follow the same routing model as pages, but the output is a Response rather than a component tree. The route file name determines the URL, and the extension in the filename is removed from the final path. For example, a file named data.json.ts becomes /data.json.

Static generation path

In static mode, Astro calls the endpoint at build time. The code runs once during the build, and Astro writes the returned body into a static file. This is ideal for outputs that do not need to change per request, such as a feed, a generated JSON document, or a precomputed asset.

If the route is dynamic, you usually pair it with getStaticPaths(). That function tells Astro which parameter values to generate. For example, a route like [id].json.ts can generate multiple files if you provide the list of IDs during the build.

The practical consequence is that the endpoint becomes part of your build pipeline. That can be a strength when you want predictable output and easy caching, but it also means the build must have access to whatever data source the endpoint needs. If the data source is unavailable during build time, the route cannot produce its file.

SSR request path

In SSR mode, the endpoint becomes a live server route. Instead of being prebuilt, it runs when a request comes in. That unlocks request-aware logic, status codes, headers, and runtime-only data access. It also means you can respond differently based on params, the request URL, or other server-side conditions.

The route can export methods such as GET, and in SSR mode it can also support other HTTP methods when needed. If a request does not match a method you exported, Astro follows its normal routing behavior, which is why endpoint design should still be deliberate rather than ad hoc.

A useful way to think about the difference is freshness versus predictability. Static endpoints are predictable because the output is fixed until the next build. SSR endpoints are fresh because they can react to the current request. Neither is universally better. The right choice depends on whether the response is content-driven or request-driven.

What the response contains

The important part is the Response object. That object carries the body and can also include headers and status codes. For binary output, the body can be an array buffer or buffer-like content. For JSON, it is usually a stringified payload with the correct content type. This is what makes astro endpoints api routes flexible enough for both simple exports and more dynamic server logic.

In practice, the response contract is what downstream tools depend on. If another system expects XML, the endpoint must return XML consistently. If a browser or integration expects a 404 when a record is missing, the endpoint should not quietly return an empty 200 response. Clear response behavior is part of the implementation, not an afterthought.

Use cases

The most common use case is a content feed. A blog, changelog, or resource library often needs RSS or JSON output so other tools can subscribe to updates. Astro endpoints are a natural fit because the feed logic can live beside the content source and be regenerated automatically.

A second use case is generated assets. The docs show that endpoints can return binary files, which means you can use them to produce images or other file-like responses. That is useful when the asset depends on site data or when you want one route to assemble a file on demand.

A third use case is lightweight API behavior for the site itself. A storefront or marketing site may need a small JSON lookup, a dynamic status response, or a route that checks whether a resource exists. In those cases, an endpoint can provide the server-side behavior without introducing a separate backend service.

For teams building content-heavy sites, endpoints also pair well with structured content workflows. If your content model is already organized, an endpoint can expose a clean machine-readable version of that data for another system to consume. If you want to keep content structured, the CMS collections guide is a useful companion because it helps you think about the source data before you expose it through a route.

There is also a practical internal-use scenario: a team may need a route that powers a preview tool, a migration script, or a scheduled job. In that case, the endpoint is not public-facing marketing infrastructure; it is a utility endpoint that keeps operational logic close to the site. That is often a better fit than building a separate internal service for one narrow task.

When deciding between a page and an endpoint, ask what the consumer needs. If the consumer is a person reading content, build a page. If the consumer is a machine, an integration, or a file-based workflow, an endpoint is usually the cleaner choice. That simple question prevents a lot of overengineering.

Typical scenarios teams run into

A content team may want a feed that updates whenever a new article is published. A developer may want a JSON route that powers a small admin tool or a preview pane. A merchant may need a downloadable file that another platform imports nightly. These are all different problems, but the same endpoint pattern can solve them because the route is defined by the output contract, not by the UI.

The important part is to match the route to the consumer’s expectations. If the consumer needs a stable URL and a fixed schema, static generation is often enough. If the consumer needs a response that changes based on the current request, SSR is the better fit. That decision keeps the implementation aligned with the actual workflow instead of forcing every output into the same pattern.

How to implement or apply it

Start by deciding whether the output can be static. If the response is based on content that changes only when you rebuild, static generation is usually simpler and cheaper to operate. If the response depends on the current request, user state, or runtime data, choose SSR so the endpoint can run on demand.

Next, choose the route shape. A file like src/pages/feed.xml.ts is appropriate for a feed, while src/pages/api/products.json.ts is better for a JSON response. If the route needs parameters, use bracket syntax such as [slug].json.ts and decide whether those values should be generated at build time or handled live.

Then implement the handler with a GET export and return a Response. Keep the body format explicit. If you are serving JSON, stringify the payload and set the content type. If you are serving an image or other binary file, return the binary body and make sure the headers match the file type.

A good workflow is to build the simplest possible endpoint first, then add complexity only when the use case demands it. For example, you might begin with a static JSON export of recent articles, then later convert it to SSR if you need request-time filtering. That keeps the route easy to reason about and avoids premature backend design.

When you implement a dynamic endpoint, decide early whether the route should be discoverable from content data or from a live lookup. If the values are known ahead of time, getStaticPaths() gives Astro the list it needs. If the values are not known until request time, keep the route in SSR mode and validate the parameter inside the handler.

It also helps to think about consumers before you ship. If the endpoint will be read by a feed reader, a browser extension, or another service, test the raw URL directly rather than only checking the page in a browser. That catches issues like incorrect headers, malformed JSON, or a response body that looks fine in source code but fails for a machine consumer.

A practical decision checklist:

  • Use static endpoints when the output can be precomputed.
  • Use SSR endpoints when the response depends on the request.
  • Use getStaticPaths() for dynamic routes in static builds.
  • Set Content-Type explicitly for non-HTML responses.
  • Return proper status codes when a resource is missing or invalid.
  • Keep endpoint logic narrow; do not turn one route into a general-purpose backend.

If your site already uses Astro for performance-focused delivery, endpoints fit naturally with that architecture. They are especially helpful when paired with rendering choices that keep page delivery efficient, such as the patterns covered in the islands architecture guide.

A simple implementation sequence

A practical way to apply the pattern is to define the contract first, then the data source, then the route. For example: decide that the endpoint should return JSON, decide which fields the consumer needs, and only then write the handler. That sequence prevents a common mistake where the route is built around whatever data is easiest to access rather than what the consumer actually needs.

If the route is public, add a quick test for the final URL and the response headers. If the route is internal, document who uses it and whether it is safe to change the schema. Those small steps make the endpoint easier to maintain when the site grows.

Common mistakes and pitfalls

The most common mistake is assuming every endpoint should be SSR. That is not true. If the output never changes between deploys, static generation is usually easier to cache, cheaper to serve, and simpler to test. Choosing SSR by default can create unnecessary runtime work.

Another frequent issue is forgetting that dynamic static endpoints need getStaticPaths(). A route with a bracketed parameter does not magically know which files to generate. If you skip that step in static mode, the build will not have enough information to create the outputs you expect.

A third pitfall is returning the wrong headers. This matters most for binary or structured formats. If you return JSON without a proper content type, or an image without the right header in SSR, consumers may not interpret the response correctly. The route may technically work while still being unreliable in practice.

Teams also sometimes overuse endpoints as if they were a full backend framework. That can lead to tangled logic, duplicated auth checks, and hard-to-test files. Endpoints are best when they are focused: one route, one responsibility, one clear response shape.

Finally, do not ignore route naming. Because the filename determines the final URL, a small naming mistake can create awkward paths or unexpected trailing-slash behavior. That is especially important for file-extension routes like XML or JSON, where the URL shape should stay predictable.

One more subtle pitfall is mixing build-time assumptions into runtime code. For example, an endpoint that works in static mode may fail in SSR if it depends on build-only data or on a file path that is not available in the deployed environment. The fix is to separate data access from response formatting so the route can be adapted more easily when the rendering mode changes.

Fixes that usually solve the problem

If a route returns the wrong format, inspect the raw response first rather than the page preview. If a dynamic static route is missing, confirm that getStaticPaths() returns every expected parameter value. If a live route is slow, check whether it can be moved back to static generation. Most endpoint problems come from a mismatch between the route’s job and the mode it is running in.

Best practices and quick checklist

The safest approach is to treat each endpoint like a public contract. Once another tool, feed reader, or integration depends on it, the response shape and status behavior should stay stable. That means you should be deliberate about content type, route naming, and error handling from the start.

Write the smallest route that solves the problem. If the endpoint only needs to expose a list of items, return that list and nothing more. If it needs to check a parameter, validate it early and respond with a clear status code when the value is missing or invalid. Small routes are easier to maintain and easier to reason about during deploys.

It also helps to keep build-time and runtime concerns separate in your head. Static endpoints are about precomputing output; SSR endpoints are about reacting to a request. When you blur those lines, you usually end up with code that is harder to debug and harder to cache.

A useful habit is to document the intended consumer in the route itself or in nearby comments. If the endpoint exists for a feed, say so. If it exists for an internal automation, note the expected format and whether the route is public. That makes future refactors safer because the next developer can see why the route exists and what would break if it changes.

Quick checklist:

  • Name the file so the final URL is obvious.
  • Decide static vs SSR before writing the logic.
  • Use getStaticPaths() when static dynamic routes need known values.
  • Return a Response with the right body format.
  • Set headers and status codes intentionally.
  • Keep the endpoint focused on one output.
  • Test the response as a consumer would, not just in the browser.
  • Revisit the route if the data source or deployment mode changes.

If you are already using Astro for content delivery, this discipline pays off quickly. Endpoints become a reliable part of the system instead of a catch-all layer that is difficult to extend later.

From practice — illustrative scenario (hypothetical, not a client project)

Illustrative example — not a real client project: Imagine a merchant running a content-rich Astro site with a blog, a small product catalog, and a newsletter signup flow. The team wants three things from the same codebase: an RSS feed for subscribers, a JSON file for an internal automation tool, and a lightweight endpoint that checks whether a slug exists before publishing a new page.

A typical setup would start with a static RSS endpoint. The content changes only when the site rebuilds, so there is no reason to make the feed run on every request. The team adds a route file that returns XML, confirms the headers are correct, and lets the host serve the file like any other static asset. That keeps the feed fast and easy to cache.

For the slug check, the team chooses SSR. This route needs to answer based on the current request and the current data source, so a live endpoint makes more sense than a build-time file. The handler reads the parameter, checks whether the slug exists, and returns a clear status code when it does not. That gives the publishing workflow a simple yes-or-no response without involving a separate service.

The internal automation export is the middle ground. If the data changes only when the content team updates the site, a static JSON endpoint is enough. If the automation needs the latest request-time state, the team can switch it to SSR later. The important takeaway is that the endpoint choice follows the data shape and freshness requirement, not the team’s habit or the perceived prestige of “having an API.”

In this scenario, the team would likely implement the routes in a sequence. First they would define the output format and consumer, then they would choose static or SSR, then they would test the raw URL with a browser and a command-line request. If the response is meant for another tool, they would verify the exact headers and status codes before wiring it into the workflow. That order matters because it prevents the common mistake of building the route before the contract is clear.

The lesson from this scenario is practical: use endpoints to remove unnecessary infrastructure, but keep each route narrow. When the output is predictable, static generation is usually the cleanest path. When the output depends on the request, SSR is the right tool. The route should serve the business need, not become a place to store every server-side idea in the project.

Astro endpoints make the most sense when you understand how they fit into the rest of the platform. If you are deciding between content sources, rendering modes, or route behavior, these related guides will help you choose the right pattern.

Explore this topic

More Astro guides, glossary entries, and practical workflows live on the topic hub.

Frequently asked questions

What are Astro endpoints used for?

Astro endpoints are used to serve non-page responses from your site, such as JSON, RSS feeds, images, or other API-style outputs. They can be generated at build time in static sites or handled on request in SSR mode. That makes them useful when you want content and data delivery in the same project.

Are Astro endpoints the same as API routes?

In practice, Astro endpoints can act like API routes when you use them to respond to requests with data or server logic. The difference is that Astro also uses the same endpoint system for static file generation, not just live server behavior. So the term covers both build-time files and runtime routes.

Do Astro endpoints need SSR?

No, Astro endpoints do not require SSR. In static mode, Astro can run the endpoint at build time and write the result as a file. SSR is only needed when you want the endpoint to run on each request and use runtime-only data or behavior.

Can Astro endpoints return binary files?

Yes. Astro endpoints can return binary responses such as images, as long as you return a proper Response object. In SSR mode, you also need to set the correct Content-Type header so the server and browser know how to handle the file.

How do dynamic Astro endpoints work?

Dynamic endpoints use bracketed route segments and can receive params, similar to pages. In static mode, you typically pair them with getStaticPaths() so Astro knows which files to generate. In server mode, the endpoint can read params at request time without getStaticPaths().

When should I use Astro endpoints instead of a separate backend?

Use Astro endpoints when the response is tightly tied to your site and you want to keep the implementation simple inside the same codebase. They are a good fit for feeds, lightweight JSON responses, generated assets, and request-time logic that does not need a full standalone backend. If you need a larger API surface, more complex auth, or many external integrations, a separate backend may still be better.

Continue reading

  1. 1Astro Adapters for Flexible Deployment

    Astro adapters connect your site to a deployment target and unlock static, server-rendered, or edge rendering. This guide explains how they work and when to use them.

  2. 2Astro SSR and Hybrid Rendering

    Astro SSR hybrid rendering lets you mix static and server-rendered pages in one project. Use it when some routes need fresh, personalized, or request-time content without giving up static performance elsewhere.

  3. 3Astro Middleware for Request Handling

    Astro middleware lets you intercept requests before a page renders, share request data through locals, and apply logic consistently across routes. This guide explains how it works and when to use it.

  4. 4Astro Prefetch for Faster Navigation

    Astro prefetch can make navigation feel instant by loading the next page before a click. This guide explains the strategies, tradeoffs, and implementation choices.

  5. 5Astro Server Islands for SEO

    A practical guide to Astro server islands for merchants and developers who want faster pages without giving up dynamic content. Learn where they help SEO, how they work, and what to avoid.