404 Status Code - Is there a Way to Change the Status Code?
This is actually expected behavior! The Sanity Content API returns a 200 status code for successful queries, even when the result is null. The query itself executed successfully - it just didn't find any matching documents. This is how GROQ and the Content API are designed to work.
The 404 handling needs to happen in your application code, not at the API level. Here's how to handle it:
In Next.js App Router (with notFound):
import { notFound } from 'next/navigation';
const query = `*[_type == "projects" && slug.current == $slug][0] {
name,
slug,
description,
image,
website
}`;
const project = await client.fetch(query, { slug: params.slug });
if (!project) {
notFound(); // This triggers Next.js 404 page
}In Next.js Pages Router:
export async function getStaticProps({ params }) {
const project = await client.fetch(query, { slug: params.slug });
if (!project) {
return {
notFound: true, // Returns 404
};
}
return {
props: { project },
};
}In a regular API route or server:
const project = await client.fetch(query, { slug });
if (!project) {
return new Response('Not Found', { status: 404 });
// or res.status(404).json({ error: 'Not found' });
}The pattern is consistent: check if the result is null, and if so, use your framework's mechanism to return a 404. This gives you full control over the 404 behavior and allows you to customize the response or redirect as needed.
This approach is actually more flexible than having the API return 404s directly, since you might want to handle missing content differently in different contexts (redirect, show a fallback, log analytics, etc.).
Sanity – Build the way you think, not the way your CMS thinks
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.